summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore3
-rwxr-xr-x[-rw-r--r--].hgtags442
-rw-r--r--BuildParams44
-rw-r--r--autobuild.xml268
-rwxr-xr-xbuild.sh68
-rw-r--r--doc/contributions.txt50
-rw-r--r--etc/message.xml28
-rw-r--r--indra/CMakeLists.txt1
-rw-r--r--indra/cmake/00-Common.cmake8
-rw-r--r--indra/cmake/Boost.cmake62
-rw-r--r--indra/cmake/CMakeLists.txt3
-rw-r--r--indra/cmake/Copy3rdPartyLibs.cmake29
-rw-r--r--indra/cmake/FindHUNSPELL.cmake38
-rw-r--r--indra/cmake/GooglePerfTools.cmake40
-rw-r--r--indra/cmake/Havok.cmake83
-rw-r--r--indra/cmake/Hunspell.cmake22
-rw-r--r--indra/cmake/LLAddBuildTest.cmake12
-rw-r--r--indra/cmake/LLCommon.cmake2
-rw-r--r--indra/cmake/LLConvexDecomposition.cmake12
-rw-r--r--indra/cmake/LLCoreHttp.cmake16
-rw-r--r--indra/cmake/LLPhysicsExtensions.cmake35
-rw-r--r--indra/cmake/LLPrimitive.cmake8
-rw-r--r--indra/cmake/Linking.cmake3
-rw-r--r--indra/cmake/Variables.cmake23
-rw-r--r--indra/cmake/ViewerMiscLibs.cmake8
-rw-r--r--indra/edit-me-to-trigger-new-build.txt1
-rw-r--r--indra/integration_tests/llimage_libtest/llimage_libtest.cpp2
-rw-r--r--indra/integration_tests/llui_libtest/CMakeLists.txt3
-rw-r--r--indra/integration_tests/llui_libtest/llui_libtest.cpp29
-rw-r--r--indra/lib/python/indra/util/llmanifest.py28
-rw-r--r--indra/linux_updater/linux_updater.cpp2
-rw-r--r--indra/llaudio/llaudioengine.cpp2
-rw-r--r--indra/llcharacter/llcharacter.cpp6
-rw-r--r--indra/llcharacter/lleditingmotion.cpp4
-rw-r--r--indra/llcharacter/llhandmotion.cpp60
-rw-r--r--indra/llcharacter/llmotioncontroller.cpp17
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/fix_macros.h25
-rw-r--r--indra/llcommon/indra_constants.h1
-rw-r--r--indra/llcommon/llallocator.cpp2
-rw-r--r--indra/llcommon/llapp.cpp3
-rw-r--r--indra/llcommon/llapr.h2
-rw-r--r--indra/llcommon/llcursortypes.cpp6
-rw-r--r--indra/llcommon/llcursortypes.h6
-rw-r--r--indra/llcommon/llerror.cpp9
-rw-r--r--indra/llcommon/llerror.h7
-rw-r--r--indra/llcommon/llerrorcontrol.h2
-rw-r--r--indra/llcommon/llhandle.h (renamed from indra/llui/llhandle.h)58
-rw-r--r--indra/llcommon/llinitparam.h16
-rw-r--r--indra/llcommon/llmemory.cpp43
-rw-r--r--indra/llcommon/llmemory.h64
-rw-r--r--indra/llcommon/llpointer.h6
-rw-r--r--indra/llcommon/llqueuedthread.cpp4
-rw-r--r--indra/llcommon/llregistry.h30
-rw-r--r--indra/llcommon/llsd.cpp1
-rw-r--r--indra/llcommon/llsdserialize.cpp88
-rw-r--r--indra/llcommon/llsdserialize.h2
-rw-r--r--indra/llcommon/llstat.cpp19
-rw-r--r--indra/llcommon/llstat.h6
-rw-r--r--indra/llcommon/llstatenums.h77
-rw-r--r--indra/llcommon/llstl.h51
-rw-r--r--indra/llcommon/llstrider.h10
-rw-r--r--indra/llcommon/llstring.cpp3
-rw-r--r--indra/llcommon/llstring.h3
-rw-r--r--indra/llcommon/llsys.cpp34
-rw-r--r--indra/llcommon/llthread.cpp42
-rw-r--r--indra/llcommon/llthread.h36
-rw-r--r--indra/llcommon/lltypeinfolookup.h141
-rw-r--r--indra/llcommon/lluri.cpp36
-rw-r--r--indra/llcommon/lluuid.cpp171
-rw-r--r--indra/llcommon/lluuid.h173
-rw-r--r--indra/llcommon/llversionviewer.h4
-rw-r--r--indra/llcommon/tests/bitpack_test.cpp1
-rw-r--r--indra/llcommon/tests/lluri_test.cpp94
-rw-r--r--indra/llcommon/tests/reflection_test.cpp2
-rw-r--r--indra/llcorehttp/CMakeLists.txt186
-rw-r--r--indra/llcorehttp/_httpinternal.h154
-rw-r--r--indra/llcorehttp/_httplibcurl.cpp373
-rw-r--r--indra/llcorehttp/_httplibcurl.h129
-rw-r--r--indra/llcorehttp/_httpopcancel.cpp73
-rw-r--r--indra/llcorehttp/_httpopcancel.h78
-rw-r--r--indra/llcorehttp/_httpoperation.cpp248
-rw-r--r--indra/llcorehttp/_httpoperation.h262
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp906
-rw-r--r--indra/llcorehttp/_httpoprequest.h219
-rw-r--r--indra/llcorehttp/_httpopsetget.cpp97
-rw-r--r--indra/llcorehttp/_httpopsetget.h83
-rw-r--r--indra/llcorehttp/_httpopsetpriority.cpp63
-rw-r--r--indra/llcorehttp/_httpopsetpriority.h73
-rw-r--r--indra/llcorehttp/_httppolicy.cpp387
-rw-r--r--indra/llcorehttp/_httppolicy.h161
-rw-r--r--indra/llcorehttp/_httppolicyclass.cpp125
-rw-r--r--indra/llcorehttp/_httppolicyclass.h59
-rw-r--r--indra/llcorehttp/_httppolicyglobal.cpp175
-rw-r--r--indra/llcorehttp/_httppolicyglobal.h66
-rw-r--r--indra/llcorehttp/_httpreadyqueue.h124
-rw-r--r--indra/llcorehttp/_httpreplyqueue.cpp107
-rw-r--r--indra/llcorehttp/_httpreplyqueue.h108
-rw-r--r--indra/llcorehttp/_httprequestqueue.cpp161
-rw-r--r--indra/llcorehttp/_httprequestqueue.h141
-rw-r--r--indra/llcorehttp/_httpretryqueue.h94
-rw-r--r--indra/llcorehttp/_httpservice.cpp348
-rw-r--r--indra/llcorehttp/_httpservice.h224
-rw-r--r--indra/llcorehttp/_mutex.h55
-rw-r--r--indra/llcorehttp/_refcounted.cpp45
-rw-r--r--indra/llcorehttp/_refcounted.h126
-rw-r--r--indra/llcorehttp/_thread.h123
-rw-r--r--indra/llcorehttp/bufferarray.cpp352
-rw-r--r--indra/llcorehttp/bufferarray.h137
-rw-r--r--indra/llcorehttp/bufferstream.cpp285
-rw-r--r--indra/llcorehttp/bufferstream.h153
-rw-r--r--indra/llcorehttp/examples/http_texture_load.cpp947
-rw-r--r--indra/llcorehttp/httpcommon.cpp179
-rw-r--r--indra/llcorehttp/httpcommon.h311
-rw-r--r--indra/llcorehttp/httphandler.h88
-rw-r--r--indra/llcorehttp/httpheaders.cpp44
-rw-r--r--indra/llcorehttp/httpheaders.h87
-rw-r--r--indra/llcorehttp/httpoptions.cpp73
-rw-r--r--indra/llcorehttp/httpoptions.h106
-rw-r--r--indra/llcorehttp/httprequest.cpp504
-rw-r--r--indra/llcorehttp/httprequest.h535
-rw-r--r--indra/llcorehttp/httpresponse.cpp91
-rw-r--r--indra/llcorehttp/httpresponse.h161
-rw-r--r--indra/llcorehttp/tests/llcorehttp_test.cpp175
-rw-r--r--indra/llcorehttp/tests/llcorehttp_test.h64
-rw-r--r--indra/llcorehttp/tests/test_allocator.cpp184
-rw-r--r--indra/llcorehttp/tests/test_allocator.h47
-rw-r--r--indra/llcorehttp/tests/test_bufferarray.hpp432
-rw-r--r--indra/llcorehttp/tests/test_bufferstream.hpp304
-rw-r--r--indra/llcorehttp/tests/test_httpheaders.hpp108
-rw-r--r--indra/llcorehttp/tests/test_httpoperation.hpp125
-rw-r--r--indra/llcorehttp/tests/test_httprequest.hpp2670
-rw-r--r--indra/llcorehttp/tests/test_httprequestqueue.hpp186
-rw-r--r--indra/llcorehttp/tests/test_httpstatus.hpp265
-rw-r--r--indra/llcorehttp/tests/test_llcorehttp_peer.py190
-rw-r--r--indra/llcorehttp/tests/test_refcounted.hpp156
-rw-r--r--indra/llcorehttp/tests/testrunner.py265
-rw-r--r--indra/llcrashlogger/llcrashlogger.cpp2
-rw-r--r--indra/llimage/llimage.cpp15
-rw-r--r--indra/llimage/llimage.h4
-rwxr-xr-x[-rw-r--r--]indra/llimage/llimagej2c.cpp0
-rw-r--r--indra/llinventory/llparcel.cpp67
-rw-r--r--indra/llinventory/llparcel.h9
-rw-r--r--indra/llkdu/llimagej2ckdu.cpp4
-rw-r--r--indra/llkdu/llimagej2ckdu.h1
-rw-r--r--indra/llkdu/llkdumem.h1
-rwxr-xr-x[-rw-r--r--]indra/llkdu/tests/llimagej2ckdu_test.cpp19
-rw-r--r--indra/llmath/CMakeLists.txt1
-rw-r--r--indra/llmath/llcamera.h12
-rw-r--r--indra/llmath/llmath.h6
-rw-r--r--indra/llmath/llmatrix3a.h2
-rw-r--r--indra/llmath/llmatrix4a.h2
-rw-r--r--indra/llmath/lloctree.h143
-rw-r--r--indra/llmath/llplane.h4
-rw-r--r--indra/llmath/llsimdmath.h3
-rw-r--r--indra/llmath/llsimdtypes.inl2
-rw-r--r--indra/llmath/llvector4a.cpp8
-rw-r--r--indra/llmath/llvector4a.h6
-rw-r--r--indra/llmath/llvector4a.inl1
-rw-r--r--indra/llmath/llvector4logical.h2
-rw-r--r--indra/llmath/llvolume.cpp56
-rw-r--r--indra/llmath/llvolume.h5
-rw-r--r--indra/llmath/llvolumeoctree.cpp6
-rw-r--r--indra/llmath/llvolumeoctree.h35
-rw-r--r--indra/llmath/tests/alignment_test.cpp139
-rw-r--r--indra/llmath/v3color.h1
-rw-r--r--indra/llmessage/llavatarnamecache.cpp99
-rw-r--r--indra/llmessage/llavatarnamecache.h7
-rw-r--r--indra/llmessage/llcurl.cpp303
-rw-r--r--indra/llmessage/llcurl.h80
-rw-r--r--indra/llmessage/llhttpassetstorage.cpp2
-rw-r--r--indra/llmessage/llsdmessagereader.cpp2
-rw-r--r--indra/llmessage/llurlrequest.cpp5
-rw-r--r--indra/llmessage/message_prehash.cpp3
-rw-r--r--indra/llmessage/message_prehash.h3
-rw-r--r--indra/llmessage/tests/llcurl_stub.cpp17
-rw-r--r--indra/llmessage/tests/llhttpclient_test.cpp4
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp2
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt3
-rw-r--r--indra/llplugin/slplugin/slplugin-objc.h24
-rw-r--r--indra/llplugin/slplugin/slplugin-objc.mm101
-rw-r--r--indra/llplugin/slplugin/slplugin.cpp131
-rw-r--r--indra/llprimitive/CMakeLists.txt2
-rw-r--r--indra/llprimitive/llmodel.cpp3
-rwxr-xr-x[-rw-r--r--]indra/llprimitive/llprimitive.cpp31
-rw-r--r--indra/llprimitive/llprimitive.h7
-rw-r--r--indra/llprimitive/object_flags.h65
-rw-r--r--indra/llrender/CMakeLists.txt2
-rw-r--r--indra/llrender/llcubemap.cpp2
-rw-r--r--indra/llrender/llfontgl.cpp14
-rw-r--r--indra/llrender/llfontgl.h4
-rw-r--r--indra/llrender/llfontregistry.cpp30
-rw-r--r--indra/llrender/llfontregistry.h4
-rw-r--r--indra/llrender/llgl.cpp90
-rw-r--r--indra/llrender/llgl.h33
-rw-r--r--indra/llrender/llglheaders.h18
-rw-r--r--indra/llrender/llglslshader.cpp11
-rw-r--r--indra/llrender/llglslshader.h4
-rw-r--r--indra/llrender/llglstates.h5
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.cpp140
-rwxr-xr-x[-rw-r--r--]indra/llrender/llimagegl.h19
-rw-r--r--indra/llrender/llrender.cpp39
-rw-r--r--indra/llrender/llrender.h1
-rw-r--r--indra/llrender/llrendernavprim.cpp59
-rw-r--r--indra/llrender/llrendernavprim.h49
-rw-r--r--indra/llrender/llrendertarget.cpp96
-rw-r--r--indra/llrender/llrendertarget.h14
-rw-r--r--indra/llrender/llshadermgr.cpp44
-rw-r--r--indra/llrender/llshadermgr.h2
-rw-r--r--indra/llrender/llvertexbuffer.cpp290
-rw-r--r--indra/llrender/llvertexbuffer.h39
-rw-r--r--indra/llui/CMakeLists.txt6
-rw-r--r--indra/llui/llcombobox.cpp3
-rw-r--r--indra/llui/llfloater.cpp22
-rw-r--r--indra/llui/llfloater.h2
-rw-r--r--indra/llui/llfloaterreg.cpp2
-rw-r--r--indra/llui/lllineeditor.cpp306
-rw-r--r--indra/llui/lllineeditor.h33
-rw-r--r--indra/llui/llmenugl.cpp10
-rw-r--r--indra/llui/llmenugl.h6
-rw-r--r--indra/llui/llnotifications.cpp30
-rw-r--r--indra/llui/llnotificationtemplate.h2
-rw-r--r--indra/llui/llpanel.cpp18
-rw-r--r--indra/llui/llpanel.h2
-rw-r--r--indra/llui/llscrollcontainer.cpp3
-rw-r--r--indra/llui/llscrolllistcolumn.cpp3
-rw-r--r--indra/llui/llscrolllistctrl.cpp196
-rw-r--r--indra/llui/llscrolllistctrl.h30
-rw-r--r--indra/llui/llspellcheck.cpp505
-rw-r--r--indra/llui/llspellcheck.h93
-rw-r--r--indra/llui/llspellcheckmenuhandler.h46
-rw-r--r--indra/llui/lltextbase.cpp273
-rw-r--r--indra/llui/lltextbase.h31
-rw-r--r--indra/llui/lltextbox.cpp2
-rw-r--r--indra/llui/lltexteditor.cpp62
-rw-r--r--indra/llui/lltexteditor.h2
-rw-r--r--indra/llui/lltoggleablemenu.cpp4
-rw-r--r--indra/llui/lltransutil.cpp13
-rw-r--r--indra/llui/llui.cpp93
-rw-r--r--indra/llui/llui.h5
-rw-r--r--indra/llui/lluicolortable.cpp18
-rw-r--r--indra/llui/lluictrlfactory.cpp55
-rw-r--r--indra/llui/lluictrlfactory.h45
-rw-r--r--indra/llui/llview.cpp12
-rw-r--r--indra/llui/llviewmodel.h1
-rw-r--r--indra/llui/tests/llurlentry_stub.cpp5
-rw-r--r--indra/llvfs/CMakeLists.txt6
-rw-r--r--indra/llvfs/lldir.cpp500
-rw-r--r--indra/llvfs/lldir.h106
-rw-r--r--indra/llvfs/lldir_linux.cpp2
-rw-r--r--indra/llvfs/lldir_linux.h2
-rw-r--r--indra/llvfs/lldir_mac.cpp239
-rw-r--r--indra/llvfs/lldir_mac.h10
-rw-r--r--indra/llvfs/lldir_solaris.cpp2
-rw-r--r--indra/llvfs/lldir_solaris.h2
-rw-r--r--indra/llvfs/lldir_win32.cpp2
-rw-r--r--indra/llvfs/lldir_win32.h2
-rw-r--r--indra/llvfs/lldiriterator.cpp7
-rw-r--r--indra/llvfs/llvfs_objc.h43
-rw-r--r--indra/llvfs/llvfs_objc.mm108
-rw-r--r--indra/llvfs/tests/lldir_test.cpp346
-rw-r--r--indra/llwindow/llkeyboard.cpp2
-rw-r--r--indra/llwindow/llkeyboard.h12
-rw-r--r--indra/llwindow/llkeyboardmacosx.cpp17
-rw-r--r--indra/llwindow/llkeyboardsdl.cpp20
-rw-r--r--indra/llwindow/llkeyboardwin32.cpp60
-rw-r--r--indra/llwindow/llwindowmacosx.cpp90
-rw-r--r--indra/llwindow/llwindowmacosx.h2
-rw-r--r--indra/llwindow/llwindowsdl.cpp9
-rw-r--r--indra/llwindow/llwindowsdl.h2
-rw-r--r--indra/llwindow/llwindowwin32.cpp10
-rw-r--r--indra/llxml/llcontrol.cpp14
-rw-r--r--indra/llxml/llcontrol.h8
-rw-r--r--indra/llxml/llxmlnode.cpp3
-rw-r--r--indra/mac_crash_logger/CMakeLists.txt5
-rw-r--r--indra/mac_crash_logger/CrashReporter.nibbin0 -> 32288 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
-rw-r--r--indra/mac_crash_logger/CrashReporter.xib3895
-rw-r--r--indra/mac_crash_logger/Info.plist8
-rw-r--r--indra/mac_crash_logger/llcrashloggermac.cpp171
-rw-r--r--indra/mac_crash_logger/llcrashloggermac.h1
-rw-r--r--indra/mac_crash_logger/llcrashloggermacdelegate.h52
-rw-r--r--indra/mac_crash_logger/llcrashloggermacdelegate.mm75
-rw-r--r--indra/mac_crash_logger/mac_crash_logger.cpp12
-rw-r--r--indra/mac_updater/mac_updater.h91
-rwxr-xr-x[-rw-r--r--]indra/newview/CMakeLists.txt122
-rw-r--r--indra/newview/app_settings/autoreplace.xml8330
-rw-r--r--indra/newview/app_settings/cmd_line.xml46
-rw-r--r--indra/newview/app_settings/keywords.ini92
-rwxr-xr-x[-rw-r--r--]indra/newview/app_settings/settings.xml549
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl5
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl103
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/binormalV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/colorV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/normalV.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/positionV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl42
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl124
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl47
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl51
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tifbin0 -> 504 bytes
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END.tifbin0 -> 556 bytes
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_END_ADD.tifbin0 -> 570 bytes
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START.tifbin0 -> 532 bytes
-rw-r--r--indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tifbin0 -> 550 bytes
-rw-r--r--indra/newview/featuretable.txt129
-rw-r--r--indra/newview/featuretable_linux.txt131
-rw-r--r--indra/newview/featuretable_mac.txt128
-rw-r--r--indra/newview/featuretable_xp.txt135
-rw-r--r--indra/newview/generate_breakpad_symbols.py51
-rw-r--r--indra/newview/gpu_table.txt1074
-rwxr-xr-xindra/newview/llagent.cpp723
-rw-r--r--indra/newview/llagent.h84
-rw-r--r--indra/newview/llagentaccess.cpp25
-rw-r--r--indra/newview/llagentaccess.h10
-rw-r--r--indra/newview/llappcorehttp.cpp192
-rw-r--r--indra/newview/llappcorehttp.h86
-rw-r--r--indra/newview/llappearancemgr.cpp12
-rw-r--r--indra/newview/llappviewer.cpp389
-rw-r--r--indra/newview/llappviewer.h15
-rw-r--r--indra/newview/llappviewerlinux.cpp2
-rw-r--r--indra/newview/llappviewerwin32.cpp7
-rw-r--r--indra/newview/llassetuploadresponders.cpp8
-rw-r--r--indra/newview/llattachmentsmgr.cpp6
-rw-r--r--indra/newview/llautoreplace.cpp811
-rw-r--r--indra/newview/llautoreplace.h231
-rw-r--r--indra/newview/llchathistory.cpp9
-rw-r--r--indra/newview/lldaycyclemanager.cpp2
-rw-r--r--indra/newview/lldirpicker.h2
-rw-r--r--indra/newview/lldrawable.cpp171
-rw-r--r--indra/newview/lldrawable.h33
-rw-r--r--indra/newview/lldrawpool.cpp46
-rw-r--r--indra/newview/lldrawpool.h8
-rw-r--r--indra/newview/lldrawpoolalpha.cpp10
-rw-r--r--indra/newview/lldrawpoolavatar.cpp84
-rw-r--r--indra/newview/lldrawpoolbump.cpp12
-rw-r--r--indra/newview/lldrawpoolterrain.cpp34
-rw-r--r--indra/newview/lldrawpoolterrain.h1
-rw-r--r--indra/newview/lldrawpooltree.cpp16
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp10
-rw-r--r--indra/newview/lldriverparam.cpp26
-rw-r--r--indra/newview/lldriverparam.h20
-rw-r--r--indra/newview/lldynamictexture.cpp8
-rw-r--r--indra/newview/lldynamictexture.h12
-rw-r--r--indra/newview/lleventpoll.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llface.cpp1287
-rw-r--r--indra/newview/llface.h26
-rw-r--r--indra/newview/llfavoritesbar.cpp4
-rw-r--r--indra/newview/llfavoritesbar.h2
-rw-r--r--indra/newview/llfeaturemanager.cpp60
-rw-r--r--indra/newview/llfeaturemanager.h4
-rw-r--r--indra/newview/llfilepicker.cpp24
-rw-r--r--indra/newview/llfilepicker.h3
-rw-r--r--indra/newview/llflexibleobject.cpp216
-rw-r--r--indra/newview/llflexibleobject.h15
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp665
-rw-r--r--indra/newview/llfloaterautoreplacesettings.h117
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp31
-rw-r--r--indra/newview/llfloaterhelpbrowser.cpp10
-rw-r--r--indra/newview/llfloaterimagepreview.cpp10
-rw-r--r--indra/newview/llfloaterland.cpp60
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp31
-rw-r--r--indra/newview/llfloatermodelpreview.h5
-rw-r--r--indra/newview/llfloatermodelwizard.cpp795
-rw-r--r--indra/newview/llfloatermodelwizard.h140
-rw-r--r--indra/newview/llfloaterpathfindingcharacters.cpp326
-rw-r--r--indra/newview/llfloaterpathfindingcharacters.h99
-rw-r--r--indra/newview/llfloaterpathfindingconsole.cpp1273
-rw-r--r--indra/newview/llfloaterpathfindingconsole.h220
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.cpp804
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.h142
-rw-r--r--indra/newview/llfloaterpathfindingobjects.cpp884
-rw-r--r--indra/newview/llfloaterpathfindingobjects.h179
-rwxr-xr-xindra/newview/llfloaterpreference.cpp50
-rw-r--r--indra/newview/llfloaterpreference.h2
-rw-r--r--indra/newview/llfloaterregioninfo.cpp147
-rw-r--r--indra/newview/llfloaterregioninfo.h4
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp491
-rw-r--r--indra/newview/llfloaterspellchecksettings.h68
-rw-r--r--indra/newview/llfloatertexturefetchdebugger.cpp158
-rw-r--r--indra/newview/llfloatertexturefetchdebugger.h5
-rw-r--r--indra/newview/llfloatertools.cpp26
-rw-r--r--indra/newview/llfloatertopobjects.cpp92
-rw-r--r--indra/newview/llfloatertopobjects.h4
-rw-r--r--indra/newview/llfloatertos.cpp6
-rw-r--r--indra/newview/llfloateruipreview.cpp122
-rw-r--r--indra/newview/llfolderview.cpp32
-rw-r--r--indra/newview/llfolderview.h2
-rw-r--r--indra/newview/llfolderviewitem.cpp4
-rw-r--r--indra/newview/llfolderviewitem.h1
-rw-r--r--indra/newview/llgroupmgr.cpp253
-rw-r--r--indra/newview/llgroupmgr.h17
-rw-r--r--indra/newview/llhints.cpp4
-rw-r--r--indra/newview/llimfloater.cpp4
-rw-r--r--indra/newview/llinventorybridge.cpp53
-rw-r--r--indra/newview/llinventorybridge.h3
-rw-r--r--indra/newview/llinventoryfunctions.cpp50
-rw-r--r--indra/newview/llinventoryfunctions.h1
-rw-r--r--indra/newview/llinventorymodel.cpp5
-rw-r--r--indra/newview/llinventorypanel.cpp1
-rw-r--r--indra/newview/lllocalbitmaps.cpp4
-rw-r--r--indra/newview/lllocationinputctrl.cpp72
-rw-r--r--indra/newview/lllocationinputctrl.h30
-rw-r--r--indra/newview/llmachineid.cpp18
-rw-r--r--indra/newview/llmaniprotate.cpp256
-rw-r--r--indra/newview/llmanipscale.cpp30
-rw-r--r--indra/newview/llmaniptranslate.cpp48
-rw-r--r--indra/newview/llmarketplacefunctions.cpp16
-rw-r--r--indra/newview/llmediactrl.cpp30
-rw-r--r--indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp238
-rw-r--r--indra/newview/llmenuoptionpathfindingrebakenavmesh.h85
-rwxr-xr-xindra/newview/llmeshrepository.cpp67
-rw-r--r--indra/newview/llmeshrepository.h3
-rw-r--r--indra/newview/llmoveview.cpp4
-rw-r--r--indra/newview/llmutelist.cpp25
-rw-r--r--indra/newview/llnamelistctrl.cpp52
-rw-r--r--indra/newview/llnamelistctrl.h57
-rw-r--r--indra/newview/llnearbychatbar.cpp2
-rw-r--r--indra/newview/llnotificationhandlerutil.cpp20
-rw-r--r--indra/newview/llnotificationmanager.cpp7
-rw-r--r--indra/newview/llpanelcontents.cpp4
-rw-r--r--indra/newview/llpaneleditwearable.cpp11
-rw-r--r--indra/newview/llpanelface.cpp80
-rw-r--r--indra/newview/llpanelface.h9
-rw-r--r--indra/newview/llpanelgroup.h2
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp109
-rw-r--r--indra/newview/llpanelgroupgeneral.h5
-rw-r--r--indra/newview/llpanelgroupinvite.cpp26
-rw-r--r--indra/newview/llpanelgroupinvite.h4
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp2
-rw-r--r--indra/newview/llpanelgrouproles.cpp90
-rw-r--r--indra/newview/llpanelgrouproles.h7
-rw-r--r--indra/newview/llpanellandmedia.cpp1
-rw-r--r--indra/newview/llpanellogin.cpp527
-rw-r--r--indra/newview/llpanellogin.h19
-rw-r--r--indra/newview/llpanelmaininventory.cpp1
-rw-r--r--indra/newview/llpanelmarketplaceinbox.cpp8
-rw-r--r--indra/newview/llpanelnearbymedia.cpp2
-rw-r--r--indra/newview/llpanelobject.cpp73
-rw-r--r--indra/newview/llpanelobject.h7
-rw-r--r--indra/newview/llpanelpermissions.cpp55
-rw-r--r--indra/newview/llpanelvolume.cpp35
-rw-r--r--indra/newview/llpanelvolume.h4
-rw-r--r--indra/newview/llpathfindingcharacter.cpp99
-rw-r--r--indra/newview/llpathfindingcharacter.h63
-rw-r--r--indra/newview/llpathfindingcharacterlist.cpp69
-rw-r--r--indra/newview/llpathfindingcharacterlist.h47
-rw-r--r--indra/newview/llpathfindinglinkset.cpp408
-rw-r--r--indra/newview/llpathfindinglinkset.h114
-rw-r--r--indra/newview/llpathfindinglinksetlist.cpp210
-rw-r--r--indra/newview/llpathfindinglinksetlist.h58
-rw-r--r--indra/newview/llpathfindingmanager.cpp1049
-rw-r--r--indra/newview/llpathfindingmanager.h127
-rw-r--r--indra/newview/llpathfindingnavmesh.cpp205
-rw-r--r--indra/newview/llpathfindingnavmesh.h91
-rw-r--r--indra/newview/llpathfindingnavmeshstatus.cpp145
-rw-r--r--indra/newview/llpathfindingnavmeshstatus.h77
-rw-r--r--indra/newview/llpathfindingnavmeshzone.cpp423
-rw-r--r--indra/newview/llpathfindingnavmeshzone.h128
-rw-r--r--indra/newview/llpathfindingobject.cpp199
-rw-r--r--indra/newview/llpathfindingobject.h92
-rw-r--r--indra/newview/llpathfindingobjectlist.cpp122
-rw-r--r--indra/newview/llpathfindingobjectlist.h68
-rw-r--r--indra/newview/llpathfindingpathtool.cpp467
-rw-r--r--indra/newview/llpathfindingpathtool.h138
-rw-r--r--indra/newview/llphysicsmotion.cpp77
-rw-r--r--indra/newview/llpolymesh.cpp210
-rw-r--r--indra/newview/llpolymesh.h62
-rw-r--r--indra/newview/llpolymorph.cpp213
-rw-r--r--indra/newview/llpolymorph.h31
-rw-r--r--indra/newview/llpreview.cpp17
-rw-r--r--indra/newview/llpreviewscript.cpp2
-rw-r--r--indra/newview/llscreenchannel.cpp40
-rw-r--r--indra/newview/llselectmgr.cpp500
-rw-r--r--indra/newview/llselectmgr.h39
-rw-r--r--indra/newview/llsidepaneliteminfo.cpp2
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp57
-rw-r--r--indra/newview/llsidepaneltaskinfo.h2
-rw-r--r--indra/newview/llslurl.cpp64
-rw-r--r--indra/newview/llslurl.h8
-rw-r--r--indra/newview/llspatialpartition.cpp547
-rw-r--r--indra/newview/llspatialpartition.h123
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartup.cpp121
-rwxr-xr-x[-rw-r--r--]indra/newview/llstartup.h2
-rw-r--r--indra/newview/llstatusbar.cpp2
-rw-r--r--indra/newview/llsurface.cpp21
-rw-r--r--indra/newview/llsurface.h1
-rw-r--r--indra/newview/llsurfacepatch.cpp14
-rw-r--r--indra/newview/llsyswellwindow.cpp4
-rw-r--r--indra/newview/lltexlayer.cpp8
-rw-r--r--indra/newview/lltexlayerparams.h40
-rw-r--r--indra/newview/lltextureatlas.cpp1
-rw-r--r--indra/newview/lltexturecache.cpp203
-rw-r--r--indra/newview/lltexturecache.h17
-rw-r--r--indra/newview/lltexturectrl.cpp71
-rw-r--r--indra/newview/lltexturectrl.h12
-rw-r--r--[-rwxr-xr-x]indra/newview/lltexturefetch.cpp2441
-rw-r--r--indra/newview/lltexturefetch.h334
-rwxr-xr-x[-rw-r--r--]indra/newview/lltextureview.cpp44
-rw-r--r--indra/newview/lltoast.cpp2
-rw-r--r--indra/newview/lltoastnotifypanel.cpp18
-rw-r--r--indra/newview/lltooldraganddrop.cpp18
-rw-r--r--indra/newview/lltooldraganddrop.h14
-rw-r--r--indra/newview/lltoolgrab.cpp18
-rw-r--r--indra/newview/lltoolmgr.cpp2
-rw-r--r--indra/newview/lltoolmgr.h6
-rw-r--r--indra/newview/lltoolmorph.cpp3
-rw-r--r--indra/newview/lltoolpie.cpp6
-rw-r--r--indra/newview/lltracker.cpp2
-rwxr-xr-xindra/newview/lltranslate.h4
-rw-r--r--indra/newview/llurldispatcher.cpp12
-rw-r--r--indra/newview/llvieweraudio.cpp61
-rw-r--r--indra/newview/llvieweraudio.h7
-rw-r--r--indra/newview/llviewercamera.h13
-rw-r--r--indra/newview/llviewercontrol.cpp37
-rw-r--r--indra/newview/llviewerdisplay.cpp75
-rw-r--r--indra/newview/llviewerfloaterreg.cpp14
-rw-r--r--indra/newview/llviewerhelp.cpp6
-rw-r--r--indra/newview/llviewerjointattachment.cpp24
-rw-r--r--indra/newview/llviewerjointmesh.cpp6
-rw-r--r--indra/newview/llviewermedia.cpp15
-rw-r--r--indra/newview/llviewermenu.cpp261
-rw-r--r--indra/newview/llviewermenu.h10
-rwxr-xr-xindra/newview/llviewermessage.cpp499
-rw-r--r--indra/newview/llviewermessage.h14
-rw-r--r--indra/newview/llviewernetwork.cpp721
-rw-r--r--indra/newview/llviewernetwork.h204
-rw-r--r--indra/newview/llviewerobject.cpp421
-rw-r--r--indra/newview/llviewerobject.h62
-rw-r--r--indra/newview/llviewerobjectlist.cpp182
-rw-r--r--indra/newview/llviewerobjectlist.h5
-rw-r--r--indra/newview/llviewerparcelmgr.cpp76
-rw-r--r--indra/newview/llviewerparcelmgr.h11
-rw-r--r--indra/newview/llviewerpartsim.cpp2
-rw-r--r--indra/newview/llviewerpartsim.h2
-rw-r--r--indra/newview/llviewerregion.cpp72
-rw-r--r--indra/newview/llviewerregion.h5
-rw-r--r--indra/newview/llviewershadermgr.cpp323
-rw-r--r--indra/newview/llviewershadermgr.h16
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerstats.cpp44
-rw-r--r--indra/newview/llviewerstats.h5
-rw-r--r--indra/newview/llviewertexture.cpp149
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewertexture.h8
-rw-r--r--indra/newview/llviewertextureanim.cpp26
-rw-r--r--indra/newview/llviewertextureanim.h11
-rw-r--r--indra/newview/llviewertexturelist.cpp237
-rw-r--r--indra/newview/llviewertexturelist.h3
-rw-r--r--indra/newview/llviewervisualparam.h8
-rwxr-xr-xindra/newview/llviewerwindow.cpp119
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatar.cpp99
-rw-r--r--indra/newview/llvoavatar.h18
-rwxr-xr-x[-rw-r--r--]indra/newview/llvoavatarself.cpp60
-rw-r--r--indra/newview/llvoavatarself.h12
-rw-r--r--indra/newview/llvograss.cpp180
-rw-r--r--indra/newview/llvograss.h2
-rw-r--r--indra/newview/llvoground.cpp15
-rw-r--r--indra/newview/llvoground.h2
-rw-r--r--indra/newview/llvopartgroup.cpp283
-rw-r--r--indra/newview/llvopartgroup.h25
-rw-r--r--indra/newview/llvosky.cpp3
-rw-r--r--indra/newview/llvosky.h2
-rw-r--r--indra/newview/llvosurfacepatch.cpp68
-rw-r--r--indra/newview/llvotree.cpp23
-rw-r--r--indra/newview/llvotree.h2
-rw-r--r--indra/newview/llvovolume.cpp1421
-rw-r--r--indra/newview/llvovolume.h13
-rw-r--r--indra/newview/llvowater.cpp15
-rw-r--r--indra/newview/llvowater.h2
-rw-r--r--indra/newview/llvowlsky.cpp4
-rw-r--r--indra/newview/llvowlsky.h2
-rw-r--r--indra/newview/llwaterparammanager.cpp2
-rw-r--r--indra/newview/llweb.cpp4
-rw-r--r--indra/newview/llwlhandlers.cpp10
-rw-r--r--indra/newview/llwlparammanager.cpp2
-rw-r--r--indra/newview/llworld.cpp14
-rw-r--r--indra/newview/macutil_Prefix.h2
-rw-r--r--indra/newview/pipeline.cpp1493
-rw-r--r--indra/newview/pipeline.h50
-rw-r--r--indra/newview/res-sdl/lltoolpathfinding.BMPbin0 -> 3126 bytes
-rw-r--r--indra/newview/res-sdl/lltoolpathfindingpathend.BMPbin0 -> 3126 bytes
-rw-r--r--indra/newview/res-sdl/lltoolpathfindingpathendadd.BMPbin0 -> 3126 bytes
-rw-r--r--indra/newview/res-sdl/lltoolpathfindingpathstart.BMPbin0 -> 3126 bytes
-rw-r--r--indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMPbin0 -> 3126 bytes
-rw-r--r--indra/newview/res/lltoolpathfinding.curbin0 -> 2238 bytes
-rw-r--r--indra/newview/res/lltoolpathfindingpathend.curbin0 -> 2238 bytes
-rw-r--r--indra/newview/res/lltoolpathfindingpathendadd.curbin0 -> 2238 bytes
-rw-r--r--indra/newview/res/lltoolpathfindingpathstart.curbin0 -> 2238 bytes
-rw-r--r--indra/newview/res/lltoolpathfindingpathstartadd.curbin0 -> 2238 bytes
-rw-r--r--indra/newview/res/viewerRes.rc6
-rw-r--r--indra/newview/skins/default/colors.xml1622
-rw-r--r--indra/newview/skins/default/textures/icons/Pathfinding_Dirty.pngbin0 -> 553 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Pathfinding_Disabled.pngbin0 -> 384 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml5
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Left.pngbin0 -> 311 bytes
-rw-r--r--indra/newview/skins/default/textures/widgets/Arrow_Right.pngbin0 -> 313 bytes
-rw-r--r--indra/newview/skins/default/xui/da/floater_model_wizard.xml241
-rw-r--r--indra/newview/skins/default/xui/da/notifications.xml1
-rw-r--r--indra/newview/skins/default/xui/da/panel_login.xml32
-rw-r--r--indra/newview/skins/default/xui/de/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/de/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/de/floater_animation_preview.xml188
-rw-r--r--indra/newview/skins/default/xui/de/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/de/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/de/floater_inventory.xml16
-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
-rw-r--r--indra/newview/skins/default/xui/de/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/de/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/de/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/de/floater_postcard.xml36
-rw-r--r--indra/newview/skins/default/xui/de/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/de/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/de/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/de/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/de/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/de/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/de/floater_top_objects.xml14
-rw-r--r--indra/newview/skins/default/xui/de/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/de/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/de/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/de/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/de/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/de/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/de/menu_viewer.xml19
-rw-r--r--indra/newview/skins/default/xui/de/notifications.xml363
-rw-r--r--indra/newview/skins/default/xui/de/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/de/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/de/panel_login.xml34
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/de/panel_region_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/de/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/de/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/de/panel_volume_pulldown.xml15
-rw-r--r--indra/newview/skins/default/xui/de/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/de/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/de/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/de/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml74
-rw-r--r--indra/newview/skins/default/xui/en/floater_autoreplace.xml289
-rw-r--r--indra/newview/skins/default/xui/en/floater_chat_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_im_session.xml8
-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
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_characters.xml209
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_console.xml419
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml597
-rw-r--r--indra/newview/skins/default/xui/en/floater_preview_notecard.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_spellcheck.xml160
-rw-r--r--indra/newview/skins/default/xui/en/floater_spellcheck_import.xml116
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml63
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml10
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml769
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml117
-rw-r--r--indra/newview/skins/default/xui/en/floater_top_objects.xml62
-rw-r--r--indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml336
-rw-r--r--indra/newview/skins/default/xui/en/menu_text_editor.xml79
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml75
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml697
-rw-r--r--indra/newview/skins/default/xui/en/panel_edit_pick.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_invite.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_login.xml475
-rw-r--r--indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_chat.xml29
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml43
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_debug.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_estate.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_toolbar_view.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_volume_pulldown.xml318
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_item_info.xml4
-rw-r--r--indra/newview/skins/default/xui/en/sidepanel_task_info.xml38
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml237
-rw-r--r--indra/newview/skins/default/xui/en/teleport_strings.xml8
-rw-r--r--indra/newview/skins/default/xui/en/widgets/location_input.xml16
-rw-r--r--indra/newview/skins/default/xui/es/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/es/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/es/floater_animation_preview.xml187
-rw-r--r--indra/newview/skins/default/xui/es/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/es/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_inventory.xml16
-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
-rw-r--r--indra/newview/skins/default/xui/es/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/es/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/es/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/es/floater_postcard.xml37
-rw-r--r--indra/newview/skins/default/xui/es/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/es/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/es/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/es/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/es/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/es/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/es/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/es/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/es/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/es/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/es/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/es/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/es/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/es/menu_viewer.xml17
-rw-r--r--indra/newview/skins/default/xui/es/notifications.xml379
-rw-r--r--indra/newview/skins/default/xui/es/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/es/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/es/panel_login.xml34
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/es/panel_region_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/es/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/es/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/es/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/es/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/es/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/es/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about.xml21
-rw-r--r--indra/newview/skins/default/xui/fr/floater_about_land.xml8
-rw-r--r--indra/newview/skins/default/xui/fr/floater_animation_preview.xml189
-rw-r--r--indra/newview/skins/default/xui/fr/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/fr/floater_camera.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml10
-rw-r--r--indra/newview/skins/default/xui/fr/floater_environment_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_god_tools.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_inventory.xml16
-rw-r--r--indra/newview/skins/default/xui/fr/floater_land_holdings.xml2
-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
-rw-r--r--indra/newview/skins/default/xui/fr/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/fr/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/fr/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/fr/floater_postcard.xml36
-rw-r--r--indra/newview/skins/default/xui/fr/floater_preview_animation.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/fr/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/floater_stats.xml11
-rw-r--r--indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/fr/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/fr/floater_tools.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/floater_top_objects.xml22
-rw-r--r--indra/newview/skins/default/xui/fr/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/fr/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/fr/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/fr/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/fr/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml23
-rw-r--r--indra/newview/skins/default/xui/fr/notifications.xml364
-rw-r--r--indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/fr/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/panel_login.xml34
-rw-r--r--indra/newview/skins/default/xui/fr/panel_postcard_settings.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_move.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_debug.xml6
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_environment.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_region_general.xml2
-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
-rw-r--r--indra/newview/skins/default/xui/fr/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_local.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_options.xml4
-rw-r--r--indra/newview/skins/default/xui/fr/panel_snapshot_postcard.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/fr/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/fr/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/fr/strings.xml52
-rw-r--r--indra/newview/skins/default/xui/fr/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/it/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/it/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/it/floater_animation_preview.xml187
-rw-r--r--indra/newview/skins/default/xui/it/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/it/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_inventory.xml16
-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
-rw-r--r--indra/newview/skins/default/xui/it/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/it/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/it/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/it/floater_postcard.xml40
-rw-r--r--indra/newview/skins/default/xui/it/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/it/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/it/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/it/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/it/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/it/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/it/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/it/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/it/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/it/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/it/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/it/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/it/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/it/menu_viewer.xml17
-rw-r--r--indra/newview/skins/default/xui/it/notifications.xml362
-rw-r--r--indra/newview/skins/default/xui/it/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/it/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/it/panel_login.xml32
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_region_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/it/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/it/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/it/panel_volume_pulldown.xml15
-rw-r--r--indra/newview/skins/default/xui/it/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/it/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/it/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/it/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/floater_animation_preview.xml187
-rw-r--r--indra/newview/skins/default/xui/ja/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_inventory.xml16
-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
-rw-r--r--indra/newview/skins/default/xui/ja/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/ja/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/ja/floater_postcard.xml42
-rw-r--r--indra/newview/skins/default/xui/ja/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/ja/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/ja/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/ja/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/ja/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/ja/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/ja/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/ja/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/ja/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/ja/menu_viewer.xml19
-rw-r--r--indra/newview/skins/default/xui/ja/notifications.xml374
-rw-r--r--indra/newview/skins/default/xui/ja/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/ja/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/ja/panel_login.xml32
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_region_texture.xml58
-rw-r--r--indra/newview/skins/default/xui/ja/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/ja/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/ja/sidepanel_item_info.xml5
-rw-r--r--indra/newview/skins/default/xui/ja/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/ja/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/ja/teleport_strings.xml8
-rw-r--r--indra/newview/skins/default/xui/pl/notifications.xml1
-rw-r--r--indra/newview/skins/default/xui/pl/panel_login.xml31
-rw-r--r--indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/floater_animation_preview.xml187
-rw-r--r--indra/newview/skins/default/xui/pt/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/pt/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/floater_inventory.xml16
-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
-rw-r--r--indra/newview/skins/default/xui/pt/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/pt/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/pt/floater_postcard.xml40
-rw-r--r--indra/newview/skins/default/xui/pt/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/pt/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/pt/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml32
-rw-r--r--indra/newview/skins/default/xui/pt/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/pt/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/pt/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/pt/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/pt/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/pt/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/pt/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/pt/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/pt/menu_viewer.xml17
-rw-r--r--indra/newview/skins/default/xui/pt/notifications.xml370
-rw-r--r--indra/newview/skins/default/xui/pt/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/pt/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/panel_login.xml35
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/pt/panel_region_texture.xml57
-rw-r--r--indra/newview/skins/default/xui/pt/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/pt/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/pt/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/pt/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/pt/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/ru/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/floater_animation_preview.xml183
-rw-r--r--indra/newview/skins/default/xui/ru/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/ru/floater_env_settings.xml25
-rw-r--r--indra/newview/skins/default/xui/ru/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/floater_inventory.xml4
-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
-rw-r--r--indra/newview/skins/default/xui/ru/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/ru/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/ru/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/ru/floater_postcard.xml33
-rw-r--r--indra/newview/skins/default/xui/ru/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/ru/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/ru/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml16
-rw-r--r--indra/newview/skins/default/xui/ru/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/ru/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/ru/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/ru/floater_water.xml70
-rw-r--r--indra/newview/skins/default/xui/ru/floater_windlight_options.xml167
-rw-r--r--indra/newview/skins/default/xui/ru/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/ru/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/ru/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/ru/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/ru/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/ru/menu_viewer.xml19
-rw-r--r--indra/newview/skins/default/xui/ru/notifications.xml357
-rw-r--r--indra/newview/skins/default/xui/ru/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/ru/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/panel_login.xml32
-rw-r--r--indra/newview/skins/default/xui/ru/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/ru/panel_region_texture.xml54
-rw-r--r--indra/newview/skins/default/xui/ru/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/ru/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/ru/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/ru/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/ru/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/ru/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about.xml19
-rw-r--r--indra/newview/skins/default/xui/tr/floater_about_land.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/floater_animation_preview.xml186
-rw-r--r--indra/newview/skins/default/xui/tr/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/tr/floater_env_settings.xml25
-rw-r--r--indra/newview/skins/default/xui/tr/floater_hardware_settings.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_inventory.xml4
-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
-rw-r--r--indra/newview/skins/default/xui/tr/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/tr/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/tr/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/tr/floater_postcard.xml33
-rw-r--r--indra/newview/skins/default/xui/tr/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/tr/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/tr/floater_stats.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml16
-rw-r--r--indra/newview/skins/default/xui/tr/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/tr/floater_tools.xml13
-rw-r--r--indra/newview/skins/default/xui/tr/floater_top_objects.xml10
-rw-r--r--indra/newview/skins/default/xui/tr/floater_water.xml70
-rw-r--r--indra/newview/skins/default/xui/tr/floater_windlight_options.xml167
-rw-r--r--indra/newview/skins/default/xui/tr/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/tr/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/tr/menu_inventory.xml1
-rw-r--r--indra/newview/skins/default/xui/tr/menu_mode_change.xml5
-rw-r--r--indra/newview/skins/default/xui/tr/menu_object.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/menu_text_editor.xml7
-rw-r--r--indra/newview/skins/default/xui/tr/menu_viewer.xml19
-rw-r--r--indra/newview/skins/default/xui/tr/notifications.xml365
-rw-r--r--indra/newview/skins/default/xui/tr/panel_bottomtray.xml47
-rw-r--r--indra/newview/skins/default/xui/tr/panel_group_invite.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/panel_login.xml32
-rw-r--r--indra/newview/skins/default/xui/tr/panel_preferences_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_debug.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_estate.xml2
-rw-r--r--indra/newview/skins/default/xui/tr/panel_region_texture.xml54
-rw-r--r--indra/newview/skins/default/xui/tr/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/tr/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/tr/sidepanel_item_info.xml3
-rw-r--r--indra/newview/skins/default/xui/tr/sidepanel_task_info.xml9
-rw-r--r--indra/newview/skins/default/xui/tr/strings.xml50
-rw-r--r--indra/newview/skins/default/xui/tr/teleport_strings.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_aaa.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_about.xml85
-rw-r--r--indra/newview/skins/default/xui/zh/floater_about_land.xml243
-rw-r--r--indra/newview/skins/default/xui/zh/floater_activeim.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_animation_anim_preview.xml11
-rw-r--r--indra/newview/skins/default/xui/zh/floater_animation_bvh_preview.xml186
-rw-r--r--indra/newview/skins/default/xui/zh/floater_animation_preview.xml186
-rw-r--r--indra/newview/skins/default/xui/zh/floater_auction.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/floater_autoreplace.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/floater_avatar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_avatar_picker.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_avatar_textures.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/floater_beacons.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/floater_build_options.xml29
-rw-r--r--indra/newview/skins/default/xui/zh/floater_bulk_perms.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_buy_contents.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/floater_buy_currency.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_buy_land.xml124
-rw-r--r--indra/newview/skins/default/xui/zh/floater_buy_object.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/floater_camera.xml23
-rw-r--r--indra/newview/skins/default/xui/zh/floater_chat_bar.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/floater_color_picker.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/floater_destinations.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_display_name.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_edit_day_cycle.xml104
-rw-r--r--indra/newview/skins/default/xui/zh/floater_edit_sky_preset.xml143
-rw-r--r--indra/newview/skins/default/xui/zh/floater_edit_water_preset.xml72
-rw-r--r--indra/newview/skins/default/xui/zh/floater_env_settings.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/floater_environment_settings.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_event.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_fast_timers.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_gesture.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_god_tools.xml86
-rw-r--r--indra/newview/skins/default/xui/zh/floater_hardware_settings.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/floater_how_to.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_im_session.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_image_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_import_collada.xml23
-rw-r--r--indra/newview/skins/default/xui/zh/floater_incoming_call.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inspect.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inventory.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inventory_item_properties.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_inventory_view_finder.xml11
-rw-r--r--indra/newview/skins/default/xui/zh/floater_joystick.xml74
-rw-r--r--indra/newview/skins/default/xui/zh/floater_lagmeter.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/floater_land_holdings.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/floater_live_lsleditor.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_lsl_guide.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/floater_map.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_media_browser.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/floater_media_settings.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_mem_leaking.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/floater_merchant_outbox.xml27
-rw-r--r--indra/newview/skins/default/xui/zh/floater_model_preview.xml312
-rw-r--r--indra/newview/skins/default/xui/zh/floater_moveview.xml20
-rw-r--r--indra/newview/skins/default/xui/zh/floater_mute_object.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_my_appearance.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_my_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_nearby_chat.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_object_weights.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/floater_openobject.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_outfit_save_as.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_outgoing_call.xml20
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pathfinding_characters.xml57
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pathfinding_console.xml121
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pathfinding_linksets.xml167
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pay.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_pay_object.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_people.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/floater_perm_prefs.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_picks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_places.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_post_process.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preferences.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preferences_proxy.xml40
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_animation.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_gesture.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_sound.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_preview_texture.xml20
-rw-r--r--indra/newview/skins/default/xui/zh/floater_price_for_listing.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/floater_publish_classified.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_report_abuse.xml92
-rw-r--r--indra/newview/skins/default/xui/zh/floater_script_preview.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_script_queue.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_script_search.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_search.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_select_key.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_sell_land.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/floater_snapshot.xml123
-rw-r--r--indra/newview/skins/default/xui/zh/floater_sound_devices.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/floater_spellcheck.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/floater_spellcheck_import.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/floater_stats.xml87
-rw-r--r--indra/newview/skins/default/xui/zh/floater_sys_well.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_telehub.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/floater_test_layout_stacks.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_test_text_vertical_aligment.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml24
-rw-r--r--indra/newview/skins/default/xui/zh/floater_texture_fetch_debugger.xml77
-rw-r--r--indra/newview/skins/default/xui/zh/floater_tools.xml319
-rw-r--r--indra/newview/skins/default/xui/zh/floater_top_objects.xml36
-rw-r--r--indra/newview/skins/default/xui/zh/floater_tos.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/floater_toybox.xml11
-rw-r--r--indra/newview/skins/default/xui/zh/floater_translation_settings.xml58
-rw-r--r--indra/newview/skins/default/xui/zh/floater_voice_controls.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/floater_voice_effect.xml147
-rw-r--r--indra/newview/skins/default/xui/zh/floater_water.xml70
-rw-r--r--indra/newview/skins/default/xui/zh/floater_windlight_options.xml167
-rw-r--r--indra/newview/skins/default/xui/zh/floater_window_size.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/floater_world_map.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/inspect_avatar.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/inspect_group.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/inspect_object.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/inspect_remote_object.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_attachment_self.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_avatar_other.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_avatar_self.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_bottomtray.xml17
-rw-r--r--indra/newview/skins/default/xui/zh/menu_edit.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_favorites.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_gesture_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_hide_navbar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inspect_object_gear.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inspect_self_gear.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inventory.xml46
-rw-r--r--indra/newview/skins/default/xui/zh/menu_inventory_add.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/menu_land.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_login.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/menu_media_ctrl.xml3
-rw-r--r--indra/newview/skins/default/xui/zh/menu_mini_map.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_model_import_gear_default.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_navbar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_nearby_chat.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_object.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/menu_object_icon.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_outfit_gear.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_participant_list.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_groups.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/menu_people_nearby.xml4
-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_picks_plus.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_profile_overflow.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/menu_save_outfit.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_text_editor.xml9
-rw-r--r--indra/newview/skins/default/xui/zh/menu_toolbars.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/menu_topinfobar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_url_http.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/menu_url_slapp.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/menu_viewer.xml392
-rw-r--r--indra/newview/skins/default/xui/zh/menu_wearable_list_item.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/menu_wearing_gear.xml1
-rw-r--r--indra/newview/skins/default/xui/zh/mime_types.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/mime_types_linux.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/mime_types_mac.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/notifications.xml2240
-rw-r--r--indra/newview/skins/default/xui/zh/panel_avatar_list_item.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/panel_body_parts_list_item.xml2
-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
-rw-r--r--indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml15
-rw-r--r--indra/newview/skins/default/xui/zh/panel_classified_info.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_cof_wearables.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_alpha.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_classified.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_eyes.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_gloves.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_hair.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_jacket.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_pants.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_pick.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_profile.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_shirt.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_shoes.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_skin.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_skirt.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_socks.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_tattoo.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_underpants.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_undershirt.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_edit_wearable.xml30
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_control_panel.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_general.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_info_sidetray.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_invite.xml19
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_land_money.xml34
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_notices.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_notify.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_group_roles.xml31
-rw-r--r--indra/newview/skins/default/xui/zh/panel_im_control_panel.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_landmark_info.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/panel_login.xml34
-rw-r--r--indra/newview/skins/default/xui/zh/panel_main_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_me.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/panel_media_settings_general.xml16
-rw-r--r--indra/newview/skins/default/xui/zh/panel_media_settings_permissions.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_media_settings_security.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_navigation_bar.xml35
-rw-r--r--indra/newview/skins/default/xui/zh/panel_navmesh_rebake.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_nearby_chat.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_nearby_media.xml18
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outfit_edit.xml10
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outfits_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_outfits_list.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_people.xml34
-rw-r--r--indra/newview/skins/default/xui/zh/panel_picks.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_place_profile.xml44
-rw-r--r--indra/newview/skins/default/xui/zh/panel_places.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_postcard_message.xml (renamed from indra/newview/skins/default/xui/zh/floater_postcard.xml)22
-rw-r--r--indra/newview/skins/default/xui/zh/panel_postcard_settings.xml23
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_advanced.xml13
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_chat.xml32
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_colors.xml11
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_general.xml31
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_graphics1.xml26
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_move.xml31
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_setup.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/panel_preferences_sound.xml34
-rw-r--r--indra/newview/skins/default/xui/zh/panel_prim_media_controls.xml24
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_covenant.xml22
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_debug.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_environment.xml33
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_estate.xml12
-rw-r--r--indra/newview/skins/default/xui/zh/panel_region_general.xml13
-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
-rw-r--r--indra/newview/skins/default/xui/zh/panel_script_ed.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_script_limits_my_avatar.xml6
-rw-r--r--indra/newview/skins/default/xui/zh/panel_script_limits_region_memory.xml8
-rw-r--r--indra/newview/skins/default/xui/zh/panel_script_question_toast.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_side_tray.xml29
-rw-r--r--indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml21
-rw-r--r--indra/newview/skins/default/xui/zh/panel_snapshot_local.xml39
-rw-r--r--indra/newview/skins/default/xui/zh/panel_snapshot_options.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/panel_snapshot_postcard.xml17
-rw-r--r--indra/newview/skins/default/xui/zh/panel_snapshot_profile.xml28
-rw-r--r--indra/newview/skins/default/xui/zh/panel_sound_devices.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/panel_stand_stop_flying.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/panel_status_bar.xml7
-rw-r--r--indra/newview/skins/default/xui/zh/panel_teleport_history.xml4
-rw-r--r--indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml14
-rw-r--r--indra/newview/skins/default/xui/zh/panel_world_map.xml46
-rw-r--r--indra/newview/skins/default/xui/zh/role_actions.xml114
-rw-r--r--indra/newview/skins/default/xui/zh/sidepanel_appearance.xml2
-rw-r--r--indra/newview/skins/default/xui/zh/sidepanel_inventory.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/sidepanel_item_info.xml23
-rw-r--r--indra/newview/skins/default/xui/zh/sidepanel_task_info.xml49
-rw-r--r--indra/newview/skins/default/xui/zh/strings.xml2404
-rw-r--r--indra/newview/skins/default/xui/zh/teleport_strings.xml30
-rw-r--r--indra/newview/skins/paths.xml10
-rw-r--r--indra/newview/tests/llagentaccess_test.cpp94
-rw-r--r--indra/newview/tests/lldir_stub.cpp4
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp8
-rw-r--r--indra/newview/tests/llslurl_test.cpp199
-rw-r--r--indra/newview/tests/lltranslate_test.cpp7
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp697
-rw-r--r--indra/newview/viewer_manifest.py301
-rw-r--r--indra/test/lluuidhashmap_tut.cpp141
-rw-r--r--indra/test/test.cpp29
-rw-r--r--indra/viewer_components/login/lllogin.cpp10
-rw-r--r--indra/viewer_components/updater/llupdatechecker.cpp62
-rw-r--r--indra/viewer_components/updater/llupdatechecker.h36
-rw-r--r--indra/viewer_components/updater/llupdaterservice.cpp2
-rw-r--r--indra/viewer_components/updater/tests/llupdaterservice_test.cpp10
1305 files changed, 81908 insertions, 25174 deletions
diff --git a/.hgignore b/.hgignore
index 501f9e6abe..b180d92003 100644
--- a/.hgignore
+++ b/.hgignore
@@ -25,6 +25,7 @@ indra/lib/mono/indra/*.exe
indra/lib/mono/indra/*.pdb
indra/lib/python/eventlet/
indra/llwindow/glh/glh_linear.h
+indra/newview/app_settings/dictionaries
indra/newview/app_settings/mozilla
indra/newview/app_settings/mozilla-runtime-*
indra/newview/app_settings/mozilla_debug
@@ -35,7 +36,7 @@ indra/newview/fmod.dll
indra/newview/mozilla-theme
indra/newview/mozilla-universal-darwin.tgz
indra/newview/res/ll_icon.*
-indra/newview/res-sdl
+indra/newview/res-sdl/ll_icon.*
indra/newview/vivox-runtime
indra/server-linux-*
indra/temp
diff --git a/.hgtags b/.hgtags
index 6dd9a0e111..25331b4894 100644..100755
--- a/.hgtags
+++ b/.hgtags
@@ -1,319 +1,393 @@
-bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
003dd9461bfa479049afcc34545ab3431b147c7c v2start
-08398e650c222336bb2b6de0cd3bba944aef11b4 2-1rn1
-0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
-12769e547e30067d494a6c01479a18107366ce2f beta-5
+52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3
+d6781e22543acd7e21b967209f3c6e7003d380e3 fork to viewer-2-0
+7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f alpha-4
+7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f fork to viewer-20qa
+d40ac9dd949cba6dab1cc386da6a2027690c2519 alpha-5
+d2382d374139850efa5bb6adfb229e3e656cfc40 howard-demo
+b8419565906e4feb434426d8d9b17dd1458e24b2 alpha-6
17fc2908e9a1ef34a9f53a41a393caf5c3cac390 beta-3-5
-19547b909b404552593be5ec7c18241e062a6d65 2-1-1-beta-1
-1e2b517adc2ecb342cd3c865f2a6ccf82a3cf8d7 2-1-beta-3
3469d90a115b900f8f250e137bbd9b684130f5d2 beta-4
-3e4b947f79d88c385e8218cbc0731cef0e42cfc4 2-1-beta-1
-434973a76ab2755f98ab55e1afc193e16692d5c5 2-1-1-beta-2
-46002088d9a4489e323b8d56131c680eaa21258c viewer-2-1-0-start
+12769e547e30067d494a6c01479a18107366ce2f beta-5
4f777ffb99fefdc6497c61385c22688ff149c659 viewer-2-0-0
-52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3
668851b2ef0f8cf8df07a0fba429e4a6c1e70abb viewer-2-0-1
-6e3b2e13906ba8ff22d3c8490b02d518adb2c907 2-1-1-beta-2
-7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f alpha-4
-7f16e79826d377f5f9f5b33dc721ab56d0d7dc8f fork to viewer-20qa
+08398e650c222336bb2b6de0cd3bba944aef11b4 2-1rn1
80bc6cff515118a36108967af49d3f8105c95bc9 viewer-2-0-2-start
-87bfaf8c76f9b22d9c65d4b315358861be87c863 2-1-1-release
+46002088d9a4489e323b8d56131c680eaa21258c viewer-2-1-0-start
+3e4b947f79d88c385e8218cbc0731cef0e42cfc4 2-1-beta-1
+0962101bfa7df0643a6e625786025fe7f8a6dc97 2-1-beta-2
+1e2b517adc2ecb342cd3c865f2a6ccf82a3cf8d7 2-1-beta-3
+c6969fe44e58c542bfc6f1bd6c0be2fa860929ac 2-1-beta-4
b03065d018b8a2e28b7de85b293a4c992cb4c12d 2-1-release
-b8419565906e4feb434426d8d9b17dd1458e24b2 alpha-6
+19547b909b404552593be5ec7c18241e062a6d65 2-1-1-beta-1
+6e3b2e13906ba8ff22d3c8490b02d518adb2c907 2-1-1-beta-2
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2-1-1-release
-c6969fe44e58c542bfc6f1bd6c0be2fa860929ac 2-1-beta-4
-d2382d374139850efa5bb6adfb229e3e656cfc40 howard-demo
-d40ac9dd949cba6dab1cc386da6a2027690c2519 alpha-5
-d6781e22543acd7e21b967209f3c6e7003d380e3 fork to viewer-2-0
+bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
c6e6324f5be1401f077ad18a4a0f6b46451c2f7b last_sprint
-7076e22f9f43f479a4ea75eac447a36364bead5a beta_2.1.3
7076e22f9f43f479a4ea75eac447a36364bead5a 2.2.0-beta1
+7076e22f9f43f479a4ea75eac447a36364bead5a DRTVWR-5_2.2.0-beta1
+7076e22f9f43f479a4ea75eac447a36364bead5a beta_2.1.3
9822eb3e25f7fe0c28ffd8aba45c507caa383cbc 2.2.0-beta2
+9822eb3e25f7fe0c28ffd8aba45c507caa383cbc DRTVWR-3_2.2.0-beta2
b0cd7e150009809a0b5b0a9d5785cd4bb230413a 2.2.0-beta3
+b0cd7e150009809a0b5b0a9d5785cd4bb230413a DRTVWR-7_2.2.0-beta3
00a831292231faad7e44c69f76cb96f175b8dfad 2.2.0-beta4
-98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-beta1
1415e6538d54fd5d568ee88343424d57c6803c2c 2.2.0-release
+1415e6538d54fd5d568ee88343424d57c6803c2c DRTVWR-8_2.2.0-release
98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-start
a3c12342b1af0951b8aa3b828aacef17fcea8178 2.3.0-beta1
+a3c12342b1af0951b8aa3b828aacef17fcea8178 DRTVWR-14_2.3.0-beta1
db0fe9bb65187f365e58a717dd23d0f4754a9c1d 2.3.0-beta2
+db0fe9bb65187f365e58a717dd23d0f4754a9c1d DRTVWR-17_2.3.0-beta2
6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-beta3
6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-release
+6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-13_2.3.0-release
+6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-20_2.3.0-beta3
dbc206fc61d89ff4cfe15aade0bf0c7bc7fee1c9 2.4.0-start
-dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
-dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e 2.4.0-beta1
+3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e DRTVWR-26_2.4.0-beta1
25bd6007e3d2fc15db9326ed4b18a24a5969a46a 2.4.0-beta2
+25bd6007e3d2fc15db9326ed4b18a24a5969a46a DRTVWR-27_2.4.0-beta2
1ed382c6a08ba3850b6ce9061bc551ddece0ea07 2.4.0-release
+1ed382c6a08ba3850b6ce9061bc551ddece0ea07 DRTVWR-25_2.4.0-release
a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
-76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b
-76f586a8e22b1abe6b2339758c8ac0fa718975de 76f586a8e22b
-0000000000000000000000000000000000000000 76f586a8e22b
-0000000000000000000000000000000000000000 76f586a8e22b
-345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b
345b17e7cf630db77e840b4fe3451bd476d750a3 2.5.0-beta1
-345b17e7cf630db77e840b4fe3451bd476d750a3 76f586a8e22b
-0000000000000000000000000000000000000000 76f586a8e22b
-54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
-b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
-7076e22f9f43f479a4ea75eac447a36364bead5a DRTVWR-5_2.2.0-beta1
-9822eb3e25f7fe0c28ffd8aba45c507caa383cbc DRTVWR-3_2.2.0-beta2
-b0cd7e150009809a0b5b0a9d5785cd4bb230413a DRTVWR-7_2.2.0-beta3
-1415e6538d54fd5d568ee88343424d57c6803c2c DRTVWR-8_2.2.0-release
-a3c12342b1af0951b8aa3b828aacef17fcea8178 DRTVWR-14_2.3.0-beta1
-db0fe9bb65187f365e58a717dd23d0f4754a9c1d DRTVWR-17_2.3.0-beta2
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-20_2.3.0-beta3
-6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 DRTVWR-13_2.3.0-release
-3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e DRTVWR-26_2.4.0-beta1
-25bd6007e3d2fc15db9326ed4b18a24a5969a46a DRTVWR-27_2.4.0-beta2
-1ed382c6a08ba3850b6ce9061bc551ddece0ea07 DRTVWR-25_2.4.0-release
345b17e7cf630db77e840b4fe3451bd476d750a3 DRTVWR-32_2.5.0-beta1
+54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
+54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
-b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
-3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
+b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
+b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
-b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
b53a0576eec80614d7767ed72b40ed67aeff27c9 2.5.2-release
-92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
-f1827b441e05bf37c68e2c15ebc6d09e9b03f527 2.6.0-start
+b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
4e9eec6a347f89b2b3f295beb72f1cf7837dff66 2.6.0-start
9283d6d1d7eb71dfe4c330e7c9144857e7356bde 2.6.0-beta1
9283d6d1d7eb71dfe4c330e7c9144857e7356bde DRTVWR-40_2.6.0-beta1
-9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
+461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
+9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
+c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
-c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
-c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
-42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
-42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
-d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
-214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
-214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
+d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
+42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
+42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
-d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
-0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
+d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
-7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
+0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
+3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
+214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
+214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
+7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
-bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
+bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
-beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
-bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
+dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
+dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
-11d5d8080e67c3955914caf98f2eb116af30e55a 2.6.9-start
+beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
+be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
+be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release
e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
-77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-57_2.6.9-beta1
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-beta1
-be2000b946f8cb3de5f44b2d419287d4c48ec4eb DRTVWR-54_2.6.8-release
-be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
-dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
-dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
-77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release
77e5a08344c95738ab879f9671b7758cddd712a3 2.6.9-release
+77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-56_2.6.9-release
+77e5a08344c95738ab879f9671b7758cddd712a3 DRTVWR-57_2.6.9-beta1
8835e0e3c0d3a48244c287bc05811dfc2fba43ec 2.7.0-start
-43c7ee846b7eed80786acbbf35d03bd016a3e85d DRTVWR-59_2.7.0-beta1
43c7ee846b7eed80786acbbf35d03bd016a3e85d 2.7.0-beta1
+43c7ee846b7eed80786acbbf35d03bd016a3e85d DRTVWR-59_2.7.0-beta1
54fd44ac92e4c61435ea33effe093a3527e18d98 2.7.1-start
-0c4d0c24278074f219e5a32e72b449e78301d11b DRTVWR-61_2.7.1-beta1
0c4d0c24278074f219e5a32e72b449e78301d11b 2.7.1-beta1
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
+0c4d0c24278074f219e5a32e72b449e78301d11b DRTVWR-61_2.7.1-beta1
9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
-e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
+e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
+fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
+fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
+fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
+fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
-be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
-057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
-057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
-be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
-09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
+09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
+e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
-502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
-2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
-6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
-6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
-e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
-2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
+057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
+057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
+6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
+6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
+502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
-29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
-29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
-4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
-4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
+2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
-29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
-29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
-599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
+29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
+29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
+4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
+4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
-fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
-fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
-46a010f4885a9d223b511eac553ba5720284b1dc 3.0.0-start
-b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
-b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
+599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
+b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
+b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
+fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
+fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
-364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
+364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-78_3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
-42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
-e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
+42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
+1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
+e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-78_3.0.0-release
-0000000000000000000000000000000000000000 DRTVWR-78_3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
-6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 3.0.3-beta1
-586907287be581817b2422b5137971b22d54ea48 3.0.4-start
-61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
+6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
-0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
+61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
+586907287be581817b2422b5137971b22d54ea48 3.0.4-start
0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
+0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
-2657fa785bbfac115852c41bd0adaff74c2ad5da DRTVWR-93_3.1.0-beta1
2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
-dbaaef19266478a20654c46395300640163e98e3 DRTVWR-96_3.1.0-beta2
-dbaaef19266478a20654c46395300640163e98e3 3.1.0-beta2
-dbaaef19266478a20654c46395300640163e98e3 DRTVWR-96_3.1.0-beta2
-bc01ee26fd0f1866e266429e85f76340523e91f1 DRTVWR-96_3.1.0-beta2
-dbaaef19266478a20654c46395300640163e98e3 3.1.0-beta2
+2657fa785bbfac115852c41bd0adaff74c2ad5da DRTVWR-93_3.1.0-beta1
bc01ee26fd0f1866e266429e85f76340523e91f1 3.1.0-beta2
-ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release
+bc01ee26fd0f1866e266429e85f76340523e91f1 DRTVWR-96_3.1.0-beta2
ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 3.1.0-release
+ae2de7b0b33c03dc5bdf3a7bfa54463b512221b2 DRTVWR-92_3.1.0-release
a8230590e28e4f30f5105549e0e43211d9d55711 3.2.0-start
-e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
e440cd1dfbd128d7d5467019e497f7f803640ad6 3.2.0-beta1
-9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2
+e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
9bcc2b7176634254e501e3fb4c5b56c1f637852e 3.2.0-beta2
-2a13d30ee50ccfed50268238e36bb90d738ccc9e DRTVWR-98_3.2.0-beta3
+9bcc2b7176634254e501e3fb4c5b56c1f637852e DRTVWR-97_3.2.0-beta2
2a13d30ee50ccfed50268238e36bb90d738ccc9e 3.2.0-beta3
-3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
-3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
-c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
-3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
+2a13d30ee50ccfed50268238e36bb90d738ccc9e DRTVWR-98_3.2.0-beta3
3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
-40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
3150219d229d628f0c15e58e8a51511cbd97e58d DRTVWR-94_3.2.0-release
-3150219d229d628f0c15e58e8a51511cbd97e58d 3.2.0-release
-9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
+c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
-523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
+9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
+40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
-80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
-a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
+523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
+a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
+80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
+3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf DRTVWR-60_2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
-a9abb9633a266c8d2fe62411cfd1c86d32da72bf 2.7.1-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
3fe994349fae64fc40874bb59db387131eb35a41 DRTVWR-104_3.2.4-beta1
-3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
-8a44ff3d2104269ce76145c2772cf1bdff2a2abe 3.2.5-start
-fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
-fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
-bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
bd6bcde2584491fd9228f1fa51c4575f4e764e19 3.2.4-release
-3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
+bd6bcde2584491fd9228f1fa51c4575f4e764e19 DRTVWR-103_3.2.4-release
+8a44ff3d2104269ce76145c2772cf1bdff2a2abe 3.2.5-start
3d2d5d244c6398a4214c666d5dd3965b0918709a 3.2.5-beta1
-65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
+3d2d5d244c6398a4214c666d5dd3965b0918709a DRTVWR-106_3.2.5-beta1
65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d 3.2.5-beta2
-c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
+65a2c1c8d855b88edfbea4e16ef2f27e7cff8b1d DRTVWR-107_3.2.5-beta2
c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
+c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
2174ed1c7129562428a5cfe8651ed77b8d26ae18 3.2.6-start
+286d73ff5c19f6c00e023dc1b60975ed6bbe2872 3.2.6-beta1
286d73ff5c19f6c00e023dc1b60975ed6bbe2872 DRTVWR-109_3.2.6-beta1
4891c46a56fed7512c783b9cbe7cb7260727bf0c 3.2.7-start
-286d73ff5c19f6c00e023dc1b60975ed6bbe2872 3.2.6-beta1
-c6175c955a19e9b9353d242889ec1779b5762522 DRTVWR-105_3.2.5-release
-c6175c955a19e9b9353d242889ec1779b5762522 3.2.5-release
-3d75c836d178c7c7e788f256afe195f6cab764a2 DRTVWR-111_3.2.7-beta1
3d75c836d178c7c7e788f256afe195f6cab764a2 3.2.7-beta1
+3d75c836d178c7c7e788f256afe195f6cab764a2 DRTVWR-111_3.2.7-beta1
89980333c99dbaf1787fe20784f1d8849e9b5d4f 3.2.8-start
-16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
-37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
16f8e2915f3f2e4d732fb3125daf229cb0fd1875 3.2.8-beta1
-987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
+16f8e2915f3f2e4d732fb3125daf229cb0fd1875 DRTVWR-114_3.2.8-beta1
987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
-51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
+987425b1acf4752379b2e1eb20944b4b35d67a85 DRTVWR-115_3.2.8-beta2
51b2fd52e36aab8f670e0874e7e1472434ec4b4a 3.2.8-release
-e9c82fca5ae6fb8a8af29012d78fb194a29323f3 DRTVWR-117_3.2.9-beta1
+51b2fd52e36aab8f670e0874e7e1472434ec4b4a DRTVWR-113_3.2.8-release
+37dd400ad721e2a89ee820ffc1e7e433c68f3ca2 3.2.9-start
e9c82fca5ae6fb8a8af29012d78fb194a29323f3 3.2.9-beta1
-a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
+e9c82fca5ae6fb8a8af29012d78fb194a29323f3 DRTVWR-117_3.2.9-beta1
a01ef9bed28627f4ca543fbc1d70c79cc297a90f 3.2.9-beta2
-987425b1acf4752379b2e1eb20944b4b35d67a85 3.2.8-beta2
-d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
+a01ef9bed28627f4ca543fbc1d70c79cc297a90f DRTVWR-118_3.2.9-beta2
d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
-5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
-5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
d5f263687f43f278107363365938f0a214920a4b 3.3.0-start
-dffd0457ee0745de65bf95f0642a5c9e46b8e2f0 viewer-beta-candidate
d5f263687f43f278107363365938f0a214920a4b DRTVWR-119
-d5f263687f43f278107363365938f0a214920a4b 3.3.0-beta1
-5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
5e8d2662f38a66eca6c591295f5880d47afc73f7 3.3.0-release
-28b95a6a28dca3338d9a1f4f204b96678df9f6a5 viewer-beta-candidate
-b43cd25be49e3984ff5361cefad020e069131d98 3.3.1-start
-3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 3.3.1-start
+3e2fca4ed1a0dc9fe6d8a6664e71098bb035a367 DRTVWR-125
28b95a6a28dca3338d9a1f4f204b96678df9f6a5 3.3.1-beta1
-1dc545e44617975da2a4a32fe303386c687a6ca1 viewer-beta-candidate
1dc545e44617975da2a4a32fe303386c687a6ca1 3.3.1-beta2
1dc545e44617975da2a4a32fe303386c687a6ca1 DRTVWR-139
-5e8d2662f38a66eca6c591295f5880d47afc73f7 viewer-release-candidate
-c623bbc854b6f7ee1b33a3718f76715046aa2937 viewer-release-candidate
+1dc545e44617975da2a4a32fe303386c687a6ca1 viewer-beta-candidate
c623bbc854b6f7ee1b33a3718f76715046aa2937 3.3.1-release
d29a260119f8d5a5d168e25fed0c7ea6b3f40161 3.3.2-beta1
675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-beta2
-c623bbc854b6f7ee1b33a3718f76715046aa2937 viewer-release-candidate
-675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
675668bd24d3bea570814f71762a2a806f7e1b8d 3.3.2-release
-675668bd24d3bea570814f71762a2a806f7e1b8d viewer-release-candidate
-600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
-24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
15e90b52dc0297921b022b90d10d797436b8a1bd viewer-release-candidate
+bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
-1b7f311b5a5dbfbed3dcbb4ed44afa20f89cad4c DRTVWR-144
-1b7f311b5a5dbfbed3dcbb4ed44afa20f89cad4c 3.3.3-beta1
+2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
+24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160
-1b7f311b5a5dbfbed3dcbb4ed44afa20f89cad4c 3.3.3-beta1
f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1
-1b7f311b5a5dbfbed3dcbb4ed44afa20f89cad4c DRTVWR-144
f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144
2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
+600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165
fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
+a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
+9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
+089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
+c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
+b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
+050e48759337249130f684b4a21080b683f61732 DRTVWR-168
+09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
+f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
+f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
+bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
+cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
+82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
+57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
+eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
+a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
+4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
+5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
+6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
+9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
+ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
+28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
+005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
+888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
+a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
+1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1
+9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
+47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
+421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192
+33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195
+e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193
+7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196
+ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
+507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197
+b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
+37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
+182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
+6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
+7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
+7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
+84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
+573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
+8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
+351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
+af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
+015012c2b740ccdec8a8c3d6e5f898449ecfe0b8 DRTVWR-213
+62b07aa81b1957897c3846292bb9412977b0af6c 3.3.4-beta6
+ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215
+733ceac77583874f3626ef7a15c105b83ef0f5bb 3.4.0-beta7
+97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release
+5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1
+b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a
+2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220
+0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221
+e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3
+f00068a66a2e2f72acbe3f690b98b323e740b289 DRTVWR-222
+305950187c628a5d6743ee9ea711cc5b9177a18e 3.4.1-beta4
+dd23d4da3bcb2ffda58569e759feb7c119982973 DRTVWR-224
+0bd3744ff060452aa13ff4992eafb381df7b1012 3.4.1-beta5
+29075f8c1abed53dcf195a59f61744e27a91108f DRTVWR-226
+fba99f381b8d4ad1b7b42fa4993b29998d95be18 DRTVWR-179
+49ed253c80bed7410e238eeab35a9f14cb034364 3.4.1-beta6
+468ca3268229011a59df99229b24315844b33d34 DRTVWR-227
+524da902713e8b60322640b9825101add4a7c497 3.4.1-beta7
+173c2809f9873499c4b9d6bc044ec941c954d3fb DRTVWR-228
+1dc94555582f52718834081e7659e973ae4521f7 3.4.1-beta8
+52c164c8023a5e65f3dc1b0bbb7fa1dd0c631b6b DRTVWR-231
+464cf7a63a9a2f95bc4972dc022ca765e93de7d3 DRTVWR-233
+637fe8bbee5e24940448198c221d5ee0fa3247b4 3.4.1-beta9
+4e0d84e92132e9e95a1d52a1e49bad69c278ea05 3.4.1-beta10
+f7cbd60a3f57ff1101157eeb79ea21e8898bedae DRTVWR-235
+baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
+18498afcdb835d6fc4d36ed935347d3b65307bad 3.4.1-beta11
+b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
+3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
+e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
+81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
+cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
+c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
+4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
+78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
+248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
+de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
+34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
+6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
+7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
+b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
+32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
+704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
+288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
+e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
+0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
+710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
+e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
+73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
+16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
+d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
+e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
+93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
+2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
+f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
+7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
+5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
+f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
+4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
+94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1
+965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252
+bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251
+ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
+48382ec79741671d19ce4cc3e8cd59e9a521e4a7 DRTVWR-254
+937ec902bb9a1cbceff17bd89e3923352b0a5fbc DRTVWR-256
+44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258
+c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257
+452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259
+daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265
+9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266
+73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267
+870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3
+0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release
+4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
+f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
+39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
+7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
+f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
+b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
+9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
+84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244
+083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1
+b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270
+cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2
+2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271
+2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3
+35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273
+c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275
diff --git a/BuildParams b/BuildParams
index 6f1af583f0..c8edfeaa2f 100644
--- a/BuildParams
+++ b/BuildParams
@@ -3,6 +3,7 @@
# Please refer to:
# https://wiki.secondlife.com/wiki/Automated_Build_System
+
# Global setting for now...
Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2"
CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2"
@@ -18,7 +19,7 @@ build_CYGWIN_Debug = false
email_status_this_is_os = true
# Limit extent of codeticket updates to revisions after...
-codeticket_since = 2.2.0-release
+codeticket_since = 3.3.0-release
# ========================================
# Viewer Development
@@ -43,18 +44,21 @@ integration_viewer-development.viewer_channel = "Second Life Development"
integration_viewer-development.login_channel = "Second Life Development"
integration_viewer-development.build_viewer_update_version_manager = false
integration_viewer-development.email = viewer-development-builds@lists.secondlife.com
-integration_viewer-development.build_enforce_coding_policy = true
-integration_viewer-development.codeticket_add_context = true
+integration_viewer-development.build_enforce_coding_policy = false
+integration_viewer-development.codeticket_add_context = false
viewer-beta.viewer_channel = "Second Life Beta Viewer"
viewer-beta.login_channel = "Second Life Beta Viewer"
viewer-beta.build_debug_release_separately = true
viewer-beta.build_viewer_update_version_manager = true
+viewer-beta.codeticket_add_context = false
viewer-release.viewer_channel = "Second Life Release"
viewer-release.login_channel = "Second Life Release"
viewer-release.build_debug_release_separately = true
viewer-release.build_viewer_update_version_manager = true
+viewer-release.codeticket_add_context = false
+
# ========================================
# mesh-development
@@ -112,31 +116,16 @@ viewer-mesh.login_channel = "Project Viewer - Mesh"
viewer-mesh.viewer_grid = aditi
viewer-mesh.email = shining@lists.lindenlab.com
-# ================
-# oz
-# ================
-
-Snowstorm_viewer-project-review.build_debug_release_separately = true
-Snowstorm_viewer-project-review.codeticket_add_context = true
-Snowstorm_viewer-project-review.viewer_channel = "Project Viewer - Snowstorm Team"
-Snowstorm_viewer-project-review.login_channel = "Project Viewer - Snowstorm Team"
-Snowstorm_viewer-project-review.codeticket_add_context = true
-
-oz_viewer-devreview.build_debug_release_separately = true
-oz_viewer-devreview.codeticket_add_context = false
-oz_viewer-devreview.build_enforce_coding_policy = true
-oz_viewer-devreview.email = oz@lindenlab.com
-
-oz_viewer-trial.build_debug_release_separately = true
-oz_viewer-trial.codeticket_add_context = false
-oz_viewer-trial.build_enforce_coding_policy = true
-oz_viewer-trial.email = oz@lindenlab.com
+# ========================================
+# viewer-pathfinding
+# ========================================
-oz_viewer-beta-review.build_debug_release_separately = true
-oz_viewer-beta-review.codeticket_add_context = false
-oz_viewer-beta-review.viewer_channel = "Second Life Beta Viewer"
-oz_viewer-beta-review.login_channel = "Second Life Beta Viewer"
-oz_viewer-beta-review.email = oz@lindenlab.com
+viewer-pathfinding.viewer_channel = "Project Viewer - Pathfinding"
+viewer-pathfinding.login_channel = "Project Viewer - Pathfinding"
+viewer-pathfinding.viewer_grid = agni
+viewer-pathfinding.build_debug_release_separately = true
+viewer-pathfinding.build_CYGWIN_Debug = false
+viewer-pathfinding.build_viewer_update_version_manager = false
# =================================================================
# asset delivery 2010 projects
@@ -199,4 +188,5 @@ runway.build_debug_release_separately = true
runway.build_CYGWIN_Debug = false
runway.build_viewer_update_version_manager = false
+
# eof
diff --git a/autobuild.xml b/autobuild.xml
index ba57d09f86..017427278e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -186,9 +186,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d98078791ce345bf6168ce9ba53ca2d7</string>
+ <string>ac37d0038c91b0672fa31a02731f0eac</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/222752/arch/Darwin/installer/boost-1.45.0-darwin-20110304.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/268347/arch/Darwin/installer/boost-1.52.0-darwin-20121218.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -198,9 +198,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a34e7fffdb94a6a4d8a2966b1f216da3</string>
+ <string>146ed8a8c2ef8ab3f0a6c4f214fc5c22</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.45.0-linux-20110310.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/268347/arch/Linux/installer/boost-1.52.0-linux-20121218.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -210,9 +210,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>98be22c8833aa2bca184b9fa09fbb82b</string>
+ <string>3ea60f17d986b7e8a3351298734bdca4</string>
<key>url</key>
- <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/boost-1.45.0-windows-20110124.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-boost/rev/268347/arch/CYGWIN/installer/boost-1.52.0-windows-20121218.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -363,6 +363,54 @@
</map>
</map>
</map>
+ <key>dictionaries</key>
+ <map>
+ <key>license</key>
+ <string>various open</string>
+ <key>license_file</key>
+ <string>LICENSES/dictionaries.txt</string>
+ <key>name</key>
+ <string>dictionaries</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>06a6c49eb1873e95623d3d2d07aee903</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Darwin/installer/dictionaries-1-darwin-20120616.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin</string>
+ </map>
+ <key>linux</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>4f0ca21d27e0cd0b002149062b0a4b25</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/Linux/installer/dictionaries-1-linux-20120616.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>linux</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>7520d75f6af325328322201c888191d4</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-dictionaries/rev/259873/arch/CYGWIN/installer/dictionaries-1-windows-20120616.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ </map>
+ </map>
<key>elfio</key>
<map>
<key>license</key>
@@ -855,6 +903,54 @@
</map>
</map>
</map>
+ <key>havok-source</key>
+ <map>
+ <key>license</key>
+ <string>havok-ares</string>
+ <key>license_file</key>
+ <string>LICENSES/havok.txt</string>
+ <key>name</key>
+ <string>havok-source</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>e6feee3b452c2f70ce8558e30d6bc10a</string>
+ <key>url</key>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/lindenlab_3p-havok-source/rev/268409/arch/Darwin/installer/havok_source-2012.1-darwin-20121219.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin</string>
+ </map>
+ <key>linux</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>0c0d2058ba48446e274d6595d1d8063e</string>
+ <key>url</key>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/lindenlab_3p-havok-source/rev/268409/arch/Linux/installer/havok_source-2012.1-linux-20121219.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>linux</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>88391b6e08d473506d406ca6f3e88cfb</string>
+ <key>url</key>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/lindenlab_3p-havok-source/rev/268409/arch/CYGWIN/installer/havok_source-2012.1-windows-20121219.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ </map>
+ </map>
<key>jpeglib</key>
<map>
<key>license</key>
@@ -966,9 +1062,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>d91e1f483209cd3eba04135c6a59e829</string>
+ <string>a5b2dff0d97b643227a58473e5c57906</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/Darwin/installer/kdu-6.4.1-darwin-20110218.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/Darwin/installer/kdu-7.0.0-darwin-20120515.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -990,9 +1086,57 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6cd9f36465ef73a3df34bf2b3bba2ced</string>
+ <string>6d80d35524e1c0c32d3385014d02d48c</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/221672/arch/CYGWIN/installer/kdu-6.4.1-windows-20110218.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-kdu-private/rev/256978/arch/CYGWIN/installer/kdu-7.0.0-windows-20120515.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>windows</string>
+ </map>
+ </map>
+ </map>
+ <key>libhunspell</key>
+ <map>
+ <key>license</key>
+ <string>libhunspell</string>
+ <key>license_file</key>
+ <string>LICENSES/hunspell.txt</string>
+ <key>name</key>
+ <string>libhunspell</string>
+ <key>platforms</key>
+ <map>
+ <key>darwin</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>6f5db0ef258df6e5c93c843ec559db6d</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Darwin/installer/libhunspell-1.3.2-darwin-20120616.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>darwin</string>
+ </map>
+ <key>linux</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>0c432d2626aea2e91a56335879c92965</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/Linux/installer/libhunspell-1.3.2-linux-20120616.tar.bz2</string>
+ </map>
+ <key>name</key>
+ <string>linux</string>
+ </map>
+ <key>windows</key>
+ <map>
+ <key>archive</key>
+ <map>
+ <key>hash</key>
+ <string>6a140e5620826aa5e587b4157f57b389</string>
+ <key>url</key>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-hunspell/rev/259874/arch/CYGWIN/installer/libhunspell-1.3.2-windows-20120616.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1095,14 +1239,14 @@
</map>
</map>
</map>
- <key>llconvexdecomposition</key>
+ <key>llphysicsextensions_source</key>
<map>
<key>license</key>
- <string>havok</string>
+ <string>TEMPORARY</string>
<key>license_file</key>
- <string>on_file</string>
+ <string>LICENSES/llphysicsextensions.txt</string>
<key>name</key>
- <string>llconvexdecomposition</string>
+ <string>llphysicsextensions_source</string>
<key>platforms</key>
<map>
<key>darwin</key>
@@ -1110,9 +1254,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>362654a472ef7368d4c803ae3fb89d95</string>
+ <string>0578fa67ef9906c6aaa326f51db2669f</string>
+ <key>hash_algorithm</key>
+ <string>md5</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Darwin/installer/llconvexdecomposition-0.1-darwin-20110819.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/263415/arch/Darwin/installer/llphysicsextensions_source-0.3-darwin-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -1122,9 +1268,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>c7801d899daec5338fbe95053255b7e7</string>
+ <string>b706fdeed4ce2182d434043dc33d9d1d</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/Linux/installer/llconvexdecomposition-0.1-linux-20110819.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/263415/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -1134,23 +1280,25 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>6ecf2f85f03c5ae87fe45769566a5660</string>
+ <string>0cebd359ea732a7db363d88f9886a1ef</string>
<key>url</key>
- <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/3p-llconvexdecomposition/rev/238959/arch/CYGWIN/installer/llconvexdecomposition-0.1-windows-20110819.tar.bz2</string>
+ <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/263415/arch/CYGWIN/installer/llphysicsextensions_source-0.3-windows-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
+ <key>version</key>
+ <string>0.2</string>
</map>
- <key>llconvexdecompositionstub</key>
+ <key>llphysicsextensions_stub</key>
<map>
<key>license</key>
- <string>lgpl</string>
+ <string>TEMPORARY</string>
<key>license_file</key>
- <string>LICENSES/LLConvexDecompositionStubLicense.txt</string>
+ <string>LICENSES/llphysicsextensions.txt</string>
<key>name</key>
- <string>llconvexdecompositionstub</string>
+ <string>llphysicsextensions_stub</string>
<key>platforms</key>
<map>
<key>darwin</key>
@@ -1158,9 +1306,11 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>a5f53e09f67271fd50f1131ffdda9d27</string>
+ <string>3ae798d4dfb54a1d806ee5f8b31f7626</string>
+ <key>hash_algorithm</key>
+ <string>md5</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Darwin/installer/llconvexdecompositionstub-0.3-darwin-20110819.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/263415/arch/Darwin/installer/llphysicsextensions_stub-0.3-darwin-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
@@ -1170,9 +1320,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>0006a964f1497f55a5f181b7042d2d22</string>
+ <string>aa8a2f25e8629cf5e6a96cc0eb93de8e</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/Linux/installer/llconvexdecompositionstub-0.3-linux-20110819.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/263415/arch/Linux/installer/llphysicsextensions_stub-0.3-linux-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -1182,14 +1332,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>b859e7e3bb03ebb467f0309f46422995</string>
+ <string>3ea4cee6a8dd4c89fbfd3ad6abd703c2</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llconvexdecompositionstub/rev/238958/arch/CYGWIN/installer/llconvexdecompositionstub-0.3-windows-20110819.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/llphysicsextensions-stub/rev/263415/arch/CYGWIN/installer/llphysicsextensions_stub-0.3-windows-20120814.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
+ <key>version</key>
+ <string>0.2</string>
</map>
<key>llqtwebkit</key>
<map>
@@ -1618,9 +1770,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>dde928cb24d22a267004a8c17669ba65</string>
+ <string>8aedfdcf670348c18a9991ae1b384a61</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/226426/arch/Linux/installer/google_perftools-1.7-linux-20110412.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string>
</map>
<key>name</key>
<string>linux</string>
@@ -1630,9 +1782,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>8308f7bd68bb7083655753b7abe7225f</string>
+ <string>f62841804acb91e1309603a84f3f0ce8</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/226287/arch/CYGWIN/installer/google_perftools-1.7-windows-20110411.tar.bz2</string>
+ <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -1762,8 +1914,12 @@
</map>
<key>package_description</key>
<map>
+ <key>description</key>
+ <string>Spell checking dictionaries</string>
+ <key>license</key>
+ <string>various open</string>
<key>name</key>
- <string>viewer_development</string>
+ <string>dictionaries</string>
<key>platforms</key>
<map>
<key>common</key>
@@ -2027,6 +2183,8 @@
<array>
<string>-configuration Release</string>
<string>-project SecondLife.xcodeproj</string>
+ <string>-DENABLE_SIGNING:BOOL=YES</string>
+ <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string>
</array>
</map>
<key>configure</key>
@@ -2054,6 +2212,8 @@
<array>
<string>-configuration Release</string>
<string>-project SecondLife.xcodeproj</string>
+ <string>-DENABLE_SIGNING:BOOL=YES</string>
+ <string>-DSIGNING_IDENTITY:STRING="Developer ID Application: Linden Research, Inc."</string>
</array>
</map>
<key>configure</key>
@@ -2303,6 +2463,18 @@
</map>
<key>configure</key>
<map>
+ <key>arguments</key>
+ <array>
+ <string>..\indra</string>
+ <string>&amp;&amp;</string>
+ <string>..\indra\tools\vstool\VSTool.exe</string>
+ <string>--solution</string>
+ <string>SecondLife.sln</string>
+ <string>--config</string>
+ <string>Debug</string>
+ <string>--startup</string>
+ <string>secondlife-bin</string>
+ </array>
<key>options</key>
<array>
<string>-G</string>
@@ -2379,6 +2551,18 @@
</map>
<key>configure</key>
<map>
+ <key>arguments</key>
+ <array>
+ <string>..\indra</string>
+ <string>&amp;&amp;</string>
+ <string>..\indra\tools\vstool\VSTool.exe</string>
+ <string>--solution</string>
+ <string>SecondLife.sln</string>
+ <string>--config</string>
+ <string>RelWithDebInfo</string>
+ <string>--startup</string>
+ <string>secondlife-bin</string>
+ </array>
<key>options</key>
<array>
<string>-G</string>
@@ -2455,6 +2639,18 @@
</map>
<key>configure</key>
<map>
+ <key>arguments</key>
+ <array>
+ <string>..\indra</string>
+ <string>&amp;&amp;</string>
+ <string>..\indra\tools\vstool\VSTool.exe</string>
+ <string>--solution</string>
+ <string>SecondLife.sln</string>
+ <string>--config</string>
+ <string>Release</string>
+ <string>--startup</string>
+ <string>secondlife-bin</string>
+ </array>
<key>options</key>
<array>
<string>-G</string>
@@ -2473,6 +2669,8 @@
<string>windows</string>
</map>
</map>
+ <key>version</key>
+ <string>1.0</string>
</map>
<key>type</key>
<string>autobuild</string>
diff --git a/build.sh b/build.sh
index 8ca3208087..15f0463aff 100755
--- a/build.sh
+++ b/build.sh
@@ -15,6 +15,12 @@
# * The basic convention is that the build name can be mapped onto a mercurial URL,
# which is also used as the "branch" name.
+check_for()
+{
+ if [ -e "$2" ]; then found_dict='FOUND'; else found_dict='MISSING'; fi
+ echo "$1 ${found_dict} '$2' " 1>&2
+}
+
build_dir_Darwin()
{
echo build-darwin-i386
@@ -59,6 +65,8 @@ pre_build()
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
+ check_for "Before 'autobuild configure'" ${build_dir}/packages/dictionaries
+
"$AUTOBUILD" configure -c $variant -- \
-DPACKAGE:BOOL=ON \
-DRELEASE_CRASH_REPORTING:BOOL=ON \
@@ -67,22 +75,56 @@ pre_build()
-DGRID:STRING="\"$viewer_grid\"" \
-DLL_TESTS:BOOL="$run_tests" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url
+
+ check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
+
end_section "Pre$variant"
}
+package_llphysicsextensions_tpv()
+{
+ begin_section "PhysicsExtensions_TPV"
+ tpv_status=0
+ if [ "$variant" = "Release" ]
+ then
+ llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml
+ "$AUTOBUILD" build --verbose --config-file $llpetpvcfg -c Tpv
+
+ # capture the package file name for use in upload later...
+ PKGTMP=`mktemp -t pgktpv.XXXXXX`
+ trap "rm $PKGTMP* 2>/dev/null" 0
+ "$AUTOBUILD" package --verbose --config-file $llpetpvcfg > $PKGTMP
+ tpv_status=$?
+ sed -n -e 's/^wrote *//p' $PKGTMP > $build_dir/llphysicsextensions_package
+ else
+ echo "Do not provide llphysicsextensions_tpv for $variant"
+ llphysicsextensions_package=""
+ fi
+ end_section "PhysicsExtensions_TPV"
+ return $tpv_status
+}
+
build()
{
local variant="$1"
if $build_viewer
then
begin_section "Viewer$variant"
- if "$AUTOBUILD" build --no-configure -c $variant
+ check_for "Before 'autobuild build'" ${build_dir}/packages/dictionaries
+
+ "$AUTOBUILD" build --no-configure -c $variant
+ viewer_build_ok=$?
+ end_section "Viewer$variant"
+ package_llphysicsextensions_tpv
+ tpvlib_build_ok=$?
+ if [ $viewer_build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
then
echo true >"$build_dir"/build_ok
else
echo false >"$build_dir"/build_ok
fi
- end_section "Viewer$variant"
+ check_for "After 'autobuild configure'" ${build_dir}/packages/dictionaries
+
fi
}
@@ -172,7 +214,10 @@ eval "$("$AUTOBUILD" source_environment)"
# dump environment variables for debugging
env|sort
+check_for "Before 'autobuild install'" ${build_dir}/packages/dictionaries
+
+check_for "After 'autobuild install'" ${build_dir}/packages/dictionaries
# Now run the build
succeeded=true
build_processes=
@@ -196,11 +241,6 @@ do
mkdir -p "$build_dir"
mkdir -p "$build_dir/tmp"
- # Install packages.
- begin_section "AutobuildInstall"
- "$AUTOBUILD" install --verbose --skip-license-check
- end_section "AutobuildInstall"
-
if pre_build "$variant" "$build_dir" >> "$build_log" 2>&1
then
if $build_link_parallel
@@ -270,13 +310,25 @@ then
upload_item quicklink "$package" binary/octet-stream
[ -f summary.json ] && upload_item installer summary.json text/plain
- # Upload crash reporter files.
case "$last_built_variant" in
Release)
+ # Upload crash reporter files
for symbolfile in $symbolfiles
do
upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream
done
+
+ # Upload the llphysicsextensions_tpv package, if one was produced
+ if [ -r "$build_dir/llphysicsextensions_package" ]
+ then
+ llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
+ upload_item private_artifact "$llphysicsextensions_package" binary/octet-stream
+ else
+ echo "No llphysicsextensions_package"
+ fi
+ ;;
+ *)
+ echo "Skipping mapfile for $last_built_variant"
;;
esac
diff --git a/doc/contributions.txt b/doc/contributions.txt
index b39cfb7b9a..c6ec40c00d 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -174,6 +174,7 @@ Ansariel Hiller
VWR-26150
STORM-1685
STORM-1713
+ STORM-1899
Aralara Rajal
Ardy Lay
STORM-859
@@ -297,6 +298,8 @@ Cherry Cheevers
ChickyBabes Zuzu
Christopher Organiser
Ciaran Laval
+Cinder Roxley
+ STORM-1703
Clara Young
Coaldust Numbers
VWR-1095
@@ -308,6 +311,7 @@ Cron Stardust
VWR-10579
VWR-25120
STORM-1075
+ STORM-1919
Cypren Christenson
STORM-417
Dante Tucker
@@ -318,6 +322,7 @@ Dale Glass
VWR-1358
VWR-2041
Darien Caldwell
+ SH-3055
Dartagan Shepherd
Debs Regent
Decro Schmooz
@@ -398,6 +403,7 @@ Gaberoonie Zanzibar
Ganymedes Costagravas
Geenz Spad
STORM-1823
+ STORM-1900
Gene Frostbite
GeneJ Composer
Geneko Nemeth
@@ -471,6 +477,7 @@ Hiro Sommambulist
VWR-143
Hitomi Tiponi
STORM-1741
+ STORM-1862
Holger Gilruth
Horatio Freund
Hoze Menges
@@ -491,6 +498,8 @@ Ima Mechanique
STORM-959
STORM-1175
STORM-1708
+ STORM-1855
+ VWR-20553
Imnotgoing Sideways
Inma Rau
Innula Zenovka
@@ -623,15 +632,29 @@ Jonathan Yap
STORM-1799
STORM-1796
STORM-1807
+ STORM-1812
+ STORM-1820
+ STORM-1839
+ STORM-1842
STORM-1808
STORM-637
STORM-1822
STORM-1809
STORM-1793
STORM-1810
+ STORM-1877
STORM-1892
+ STORM-1894
+ STORM-1860
+ STORM-1852
+ STORM-1870
+ STORM-1872
+ STORM-1858
+ STORM-1862
+ STORM-1918
Kadah Coba
STORM-1060
+ STORM-1843
Jondan Lundquist
Josef Munster
Josette Windlow
@@ -642,6 +665,8 @@ Kage Pixel
VWR-11
Kagehi Kohn
Kaimen Takahe
+Katharine Berry
+ STORM-1900
Keklily Longfall
Ken Lavender
Ken March
@@ -726,6 +751,9 @@ Marc2 Sands
Marianne McCann
Marine Kelley
STORM-281
+MartinRJ Fayray
+ STORM-1844
+ STORM-1845
Matthew Anthony
Matthew Dowd
VWR-1344
@@ -869,6 +897,10 @@ Nicholaz Beresford
VWR-2682
VWR-2684
Nick Rhodes
+NickyD
+ MAINT-873
+Nicky Dasmijn
+ VWR-29228
Nicky Perian
OPEN-1
STORM-1087
@@ -1010,6 +1042,7 @@ Satanello Miami
Satomi Ahn
STORM-501
STORM-229
+ VWR-20553
VWR-24502
Scrim Pinion
Scrippy Scofield
@@ -1036,9 +1069,12 @@ Shawn Kaufmat
SNOW-240
Sheet Spotter
Shnurui Troughton
+Shyotl Kuhr
+ MAINT-1138
Siana Gearz
STORM-960
STORM-1088
+ MAINT-1138
sicarius Thorne
Sicarius Toxx
SignpostMarv Martin
@@ -1053,6 +1089,8 @@ Simon Nolan
Sini Nubalo
Sitearm Madonna
SLB Wirefly
+Slee Mayo
+ SEC-1075
snowy Sidran
SpacedOut Frye
VWR-34
@@ -1092,10 +1130,14 @@ Sudane Erato
Synystyr Texan
Takeda Terrawyng
TankMaster Finesmith
+ OPEN-140
+ OPEN-142
STORM-1100
- STORM-1602
STORM-1258
+ STORM-1602
+ STORM-1868
VWR-26622
+ VWR-29224
Talamasca
Tali Rosca
Tayra Dagostino
@@ -1212,6 +1254,9 @@ Watty Berkson
Westley Schridde
Westley Streeter
Whimsy Winx
+Whirly Fizzle
+ STORM-1895
+ MAINT-873
Whoops Babii
VWR-631
VWR-1640
@@ -1240,6 +1285,8 @@ Whoops Babii
Winter Ventura
Wilton Lundquist
VWR-7682
+Wolf Loonie
+ STORM-1868
WolfPup Lowenhar
OPEN-1
OPEN-37
@@ -1288,6 +1335,7 @@ Zi Ree
VWR-24017
VWR-25588
STORM-1790
+ STORM-1842
Zipherius Turas
VWR-76
VWR-77
diff --git a/etc/message.xml b/etc/message.xml
index 3445975545..6d8160abb5 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -385,14 +385,6 @@
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
-
- <key>ParcelMediaURLFilter</key>
- <map>
- <key>flavor</key>
- <string>llsd</string>
- <key>trusted-sender</key>
- <boolean>false</boolean>
- </map>
<key>ParcelNavigateMedia</key>
<map>
@@ -546,8 +538,24 @@
<key>trusted-sender</key>
<boolean>true</boolean>
</map>
-
- <!-- UDPDeprecated Messages -->
+
+ <key>NavMeshStatusUpdate</key>
+ <map>
+ <key>flavor</key>
+ <string>llsd</string>
+ <key>trusted-sender</key>
+ <boolean>true</boolean>
+ </map>
+
+ <key>AgentStateUpdate</key>
+ <map>
+ <key>flavor</key>
+ <string>llsd</string>
+ <key>trusted-sender</key>
+ <boolean>true</boolean>
+ </map>
+
+ <!-- UDPDeprecated Messages -->
<key>ScriptRunningReply</key>
<map>
<key>flavor</key>
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 1cebb53a07..24c98bfada 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -43,6 +43,7 @@ add_subdirectory(cmake)
add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
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)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 98eeed09b3..452fd5f356 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -51,6 +51,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 +70,7 @@ if (WINDOWS)
/Oy-
/Zc:wchar_t-
/arch:SSE2
+ /fp:fast
)
# Are we using the crummy Visual Studio KDU build workaround?
@@ -198,13 +200,17 @@ if (DARWIN)
add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
set(CMAKE_CXX_LINK_FLAGS "-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)
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index 2135f0584c..1acb2bbbfd 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -12,12 +12,13 @@ if (STANDALONE)
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_PROGRAM_OPTIONS_LIBRARY
optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
@@ -37,22 +38,55 @@ else (STANDALONE)
else(MSVC80)
# MSVC 10.0 config
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_SYSTEM_LIBRARY
- optimized libboost_system-vc100-mt-${BOOST_VERSION}
- debug libboost_system-vc100-mt-gd-${BOOST_VERSION})
+ optimized libboost_system-mt
+ debug libboost_system-mt-gd)
set(BOOST_FILESYSTEM_LIBRARY
- optimized libboost_filesystem-vc100-mt-${BOOST_VERSION}
- debug libboost_filesystem-vc100-mt-gd-${BOOST_VERSION})
+ optimized libboost_filesystem-mt
+ debug libboost_filesystem-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_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_SYSTEM_LIBRARY
+ optimized boost_system-mt
+ debug boost_system-mt-d)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized boost_filesystem-mt
+ debug boost_filesystem-mt-d)
+ set(BOOST_THREAD_LIBRARY
+ optimized boost_thread-mt
+ debug boost_thread-mt-d)
+ elseif (DARWIN)
+ set(BOOST_PROGRAM_OPTIONS_LIBRARY
+ optimized boost_program_options-mt
+ debug boost_program_options-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_SYSTEM_LIBRARY
+ optimized boost_system-mt
+ debug boost_system-mt-d)
+ set(BOOST_FILESYSTEM_LIBRARY
+ optimized boost_filesystem-mt
+ debug boost_filesystem-mt-d)
+ set(BOOST_THREAD_LIBRARY
+ optimized boost_thread-mt
+ debug boost_thread-mt-d)
endif (WINDOWS)
endif (STANDALONE)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 279d577a27..569034a6fb 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -37,12 +37,12 @@ set(cmake_SOURCE_FILES
GLOD.cmake
GStreamer010Plugin.cmake
GooglePerfTools.cmake
+ Hunspell.cmake
JPEG.cmake
LLAddBuildTest.cmake
LLAudio.cmake
LLCharacter.cmake
LLCommon.cmake
- LLConvexDecomposition.cmake
LLCrashLogger.cmake
LLDatabase.cmake
LLImage.cmake
@@ -53,6 +53,7 @@ set(cmake_SOURCE_FILES
LLMessage.cmake
LLPlugin.cmake
LLPrimitive.cmake
+ LLPhysicsExtensions.cmake
LLRender.cmake
LLScene.cmake
LLTestCommand.cmake
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 394db362b1..c32e357da3 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -41,6 +41,7 @@ if(WINDOWS)
libeay32.dll
libcollada14dom22-d.dll
glod.dll
+ libhunspell.dll
)
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
@@ -53,12 +54,13 @@ 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)
@@ -212,11 +214,12 @@ 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
@@ -251,30 +254,40 @@ elseif(LINUX)
libapr-1.so.0
libaprutil-1.so.0
libatk-1.0.so
+ libboost_program_options-mt.so.${BOOST_VERSION}.0
+ libboost_regex-mt.so.${BOOST_VERSION}.0
+ libboost_thread-mt.so.${BOOST_VERSION}.0
+ libboost_filesystem-mt.so.${BOOST_VERSION}.0
+ libboost_signals-mt.so.${BOOST_VERSION}.0
+ libboost_system-mt.so.${BOOST_VERSION}.0
libbreakpad_client.so.0
libcollada14dom.so
libcrypto.so.1.0.0
libdb-5.1.so
libexpat.so
libexpat.so.1
- libglod.so
+ 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 (USE_TCMALLOC)
+ set(release_files ${release_files} "libtcmalloc_minimal.so")
+ endif (USE_TCMALLOC)
+
if (FMOD)
set(release_files ${release_files} "libfmod-3.75.so")
endif (FMOD)
diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake
new file mode 100644
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/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake
index d9f91193be..73b3642ae6 100644
--- 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(tcmalloc)
+ 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(tcmalloc)
+ 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 100644
index 0000000000..5c0768abfa
--- /dev/null
+++ b/indra/cmake/Havok.cmake
@@ -0,0 +1,83 @@
+# -*- cmake -*-
+
+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)
+
+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(cmd "mkdir")
+ 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}")
+
+ exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
+ 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")
+ exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+ exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+ file(GLOB extracted_debug "${debug_dir}/*.o")
+ file(GLOB extracted_release "${release_dir}/*.o")
+ file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+ 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)
+
diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake
new file mode 100644
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/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 08feab6e36..21a0c8a9ca 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 ${TCMALLOC_LINK_FLAGS}"
+ 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/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 17e211cb99..8f7bb296ce 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -24,7 +24,7 @@ endif (LINUX)
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 100644
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/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake
new file mode 100644
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/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index f15a2c2649..ab39cbb6be 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -15,10 +15,10 @@ 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
+ debug libboost_filesystem-mt-gd
+ optimized libboost_filesystem-mt
+ debug libboost_system-mt-gd
+ optimized libboost_system-mt
)
else (WINDOWS)
set(LLPRIMITIVE_LIBRARIES
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 47f944f9a5..c3e3a80fd0 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -38,9 +38,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)
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 4cbf7aa043..a64ce2d4ba 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -99,10 +99,20 @@ 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.2)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
+ else (XCODE_VERSION GREATER 4.2)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)
+ endif (XCODE_VERSION GREATER 4.2)
+
+ set(CMAKE_OSX_SYSROOT macosx10.6)
+ 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:
@@ -131,9 +141,14 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
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_CHANNEL "Second Life Developer" CACHE STRING "Viewer Channel Name")
set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
+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.")
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index df013b1665..5b00c989a4 100644
--- 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/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index e69de29bb2..0f6a8b8a1d 100644
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -0,0 +1 @@
+Wed Nov 7 00:25:19 UTC 2012
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 36c5b67826..034c816742 100644
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -240,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);
}
}
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 633ad84159..91c9f20c10 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -18,6 +18,7 @@ include(LLWindow)
include(LLUI)
include(LLVFS) # ugh, needed for LLDir
include(LLXML)
+include(Hunspell)
include(Linking)
# include(Tut)
@@ -31,6 +32,7 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LIBS_PREBUILD_DIR}/include/hunspell
)
set(llui_libtest_SOURCE_FILES
@@ -78,6 +80,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
--- 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/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index a4fb77357c..97cc31bba0 100644
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -167,7 +167,12 @@ ARGUMENTS=[
dict(name='version',
description="""This specifies the version of Second Life that is
being packaged up.""",
- default=get_default_version)
+ default=get_default_version),
+ 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=""):
@@ -621,6 +626,23 @@ 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()
@@ -666,6 +688,10 @@ class LLManifest(object):
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/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index 277f0a5367..991dfd9dce 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -251,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)
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 72c0091d17..ef560cd7fc 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1792,5 +1792,3 @@ bool LLAudioData::load()
mBufferp->mAudioDatap = this;
return true;
}
-
-
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index c9fb8534f1..0a6a8f9fa6 100644
--- 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);
+ }
}
}
diff --git a/indra/llcharacter/lleditingmotion.cpp b/indra/llcharacter/lleditingmotion.cpp
index 66b3c2bd25..0d0b85ba60 100644
--- 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());
diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp
index 63937d8255..696dba0d95 100644
--- 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/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index bb892f4a7f..4f6351709e 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -542,6 +542,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 +701,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 +815,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 +837,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
+
return;
}
@@ -850,7 +856,7 @@ void LLMotionController::updateMotions(bool force_update)
}
updateLoadingMotions();
-
+
resetJointSignatures();
if (mPaused && !force_update)
@@ -861,11 +867,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/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index dd7b8c6eb8..66e2bc9095 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -116,6 +116,7 @@ set(llcommon_HEADER_FILES
bitpack.h
ctype_workaround.h
doublelinkedlist.h
+ fix_macros.h
imageids.h
indra_constants.h
linden_common.h
@@ -174,6 +175,7 @@ set(llcommon_HEADER_FILES
llfoldertype.h
llformat.h
llframetimer.h
+ llhandle.h
llhash.h
llheartbeat.h
llhttpstatuscodes.h
diff --git a/indra/llcommon/fix_macros.h b/indra/llcommon/fix_macros.h
new file mode 100644
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/indra_constants.h b/indra/llcommon/indra_constants.h
index 0745696ef3..0da83720bd 100644
--- 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/llallocator.cpp b/indra/llcommon/llallocator.cpp
index 6f6abefc67..87654b5b97 100644
--- 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"
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index ed192a9975..ca258900c7 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -289,6 +289,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 +301,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.
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index af33ce666f..034546c3f3 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -168,7 +168,7 @@ public:
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)
private:
apr_uint32_t mData;
diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp
index e987c397bd..ec60097195 100644
--- 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
--- 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/llerror.cpp b/indra/llcommon/llerror.cpp
index 7e6eee0f3c..9b0141eb76 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -534,7 +534,7 @@ namespace
}
- void commonInit(const std::string& dir)
+ void commonInit(const std::string& dir, bool log_to_stderr = true)
{
LLError::Settings::reset();
@@ -542,7 +542,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 +581,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)
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index b3e604f8e8..b65b410153 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -35,7 +35,7 @@
#include "stdtypes.h"
-/* Error Logging Facility
+/** Error Logging Facility
Information for most users:
@@ -100,7 +100,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 +142,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();
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index d53a819d88..480654b1a2 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -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
diff --git a/indra/llui/llhandle.h b/indra/llcommon/llhandle.h
index 37c657dd92..6af5e198d6 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llcommon/llhandle.h
@@ -31,6 +31,10 @@
#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:
@@ -42,15 +46,37 @@ 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
-
+/**
+ * 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
{
@@ -108,6 +134,14 @@ private:
}
};
+/**
+ * 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>
{
@@ -144,8 +178,10 @@ 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
+/**
+ * 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
{
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 99983a19cb..9a6d1eff5c 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -35,7 +35,7 @@
#include <boost/shared_ptr.hpp>
#include "llerror.h"
-#include "lltypeinfolookup.h"
+#include "llstl.h"
namespace LLInitParam
{
@@ -212,14 +212,6 @@ namespace LLInitParam
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;
@@ -228,9 +220,9 @@ namespace LLInitParam
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 LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t;
- typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t;
- typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_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;
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 3b9758f996..70ad10ad55 100644
--- 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..10013e0f92 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -27,7 +27,13 @@
#define LLMEMORY_H
#include "llmemtype.h"
-#if LL_DEBUG
+
+#if LL_WINDOWS && LL_DEBUG
+#define LL_CHECK_MEMORY llassert(_CrtCheckMemory());
+#else
+#define LL_CHECK_MEMORY
+#endif
+
inline void* ll_aligned_malloc( size_t size, int align )
{
void* mem = malloc( size + (align - 1) + sizeof(void*) );
@@ -43,10 +49,11 @@ inline void ll_aligned_free( void* ptr )
free( ((void**)ptr)[-1] );
}
+#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 +68,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 +76,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 +123,13 @@ 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
#ifndef __DEBUG_PRIVATE_MEM__
#define __DEBUG_PRIVATE_MEM__ 0
@@ -512,4 +539,13 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr)
// LLSingleton moved to llsingleton.h
+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
+
+
#endif
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index affa040602..88c09c8dca 100644
--- 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/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 1738c16dea..abf47a0f57 100644
--- 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/llregistry.h b/indra/llcommon/llregistry.h
index 36d7f7a44c..853c427a13 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -31,30 +31,16 @@
#include <boost/type_traits.hpp>
#include "llsingleton.h"
-#include "lltypeinfolookup.h"
+#include "llstl.h"
template <typename T>
-class LLRegistryDefaultComparator
+struct LLRegistryDefaultComparator
{
- bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; }
-};
-
-template <typename KEY, typename VALUE>
-struct LLRegistryMapSelector
-{
- typedef std::map<KEY, VALUE> type;
-};
-
-template <typename VALUE>
-struct LLRegistryMapSelector<std::type_info*, VALUE>
-{
- typedef LLTypeInfoLookup<VALUE> type;
-};
-
-template <typename VALUE>
-struct LLRegistryMapSelector<const std::type_info*, VALUE>
-{
- typedef LLTypeInfoLookup<VALUE> type;
+ 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> >
@@ -72,7 +58,7 @@ public:
{
friend class LLRegistry<KEY, VALUE, COMPARATOR>;
public:
- typedef typename LLRegistryMapSelector<KEY, VALUE>::type registry_map_t;
+ typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t;
bool add(ref_const_key_t key, ref_const_value_t value)
{
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index e295e3c621..8276ec836a 100644
--- 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
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index b419101b7e..6b549e4b6f 100644
--- 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);
+ LLSD::UUID value = data.asUUID();
+ ostr.write((const char*)(&value.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..86e3fc864c 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -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/llstat.cpp b/indra/llcommon/llstat.cpp
index 057257057f..b82d52797e 100644
--- a/indra/llcommon/llstat.cpp
+++ b/indra/llcommon/llstat.cpp
@@ -40,7 +40,6 @@
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
@@ -771,13 +770,19 @@ void LLStat::init()
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::stat_map_t& LLStat::getStatList()
+{
+ static LLStat::stat_map_t stat_list;
+ return stat_list;
+}
+
LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer)
: mUseFrameTimer(use_frame_timer),
mNumBins(num_bins)
@@ -803,10 +808,10 @@ LLStat::~LLStat()
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);
}
}
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
index b877432e86..1a8404cc07 100644
--- a/indra/llcommon/llstat.h
+++ b/indra/llcommon/llstat.h
@@ -263,9 +263,9 @@ 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);
@@ -342,8 +342,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
--- 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/llstl.h b/indra/llcommon/llstl.h
index 8ad12c9a03..d3941e1bc9 100644
--- 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/llstrider.h b/indra/llcommon/llstrider.h
index f4c43bac61..ed9284d2c5 100644
--- 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 fa0eb9f72c..0c32679744 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -47,7 +47,8 @@ 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();
}
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 09733e8e2a..119efc7957 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -183,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; }
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 6073bcd0a6..c96f2191f3 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -944,13 +944,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 +984,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
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index a6ad6b125c..1d56a52c32 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -71,6 +71,13 @@ LL_COMMON_API void assert_main_thread()
}
}
+void LLThread::registerThreadID()
+{
+#if !LL_DARWIN
+ sThreadID = ++sIDIter;
+#endif
+}
+
//
// Handed to the APR thread creation function
//
@@ -114,7 +121,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 +180,10 @@ void LLThread::shutdown()
}
delete mRunCondition;
- mRunCondition = 0;
+ mRunCondition = NULL;
+
+ delete mDataLock;
+ mDataLock = NULL;
if (mIsLocalPool && mAPRPoolp)
{
@@ -242,28 +252,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 +297,12 @@ void LLThread::yield()
void LLThread::wake()
{
- mRunCondition->lock();
+ mDataLock->lock();
if(!shouldSleep())
{
mRunCondition->signal();
}
- mRunCondition->unlock();
+ mDataLock->unlock();
}
void LLThread::wakeLocked()
@@ -481,6 +493,19 @@ LLThreadSafeRefCount::LLThreadSafeRefCount() :
{
}
+LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
+{
+ if (sMutex)
+ {
+ sMutex->lock();
+ }
+ mRef = 0;
+ if (sMutex)
+ {
+ sMutex->unlock();
+ }
+}
+
LLThreadSafeRefCount::~LLThreadSafeRefCount()
{
if (mRef != 0)
@@ -489,6 +514,7 @@ LLThreadSafeRefCount::~LLThreadSafeRefCount()
}
}
+
//============================================================================
LLResponder::~LLResponder()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index b52e70ab2e..5c8bbca2ca 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -88,6 +88,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 +102,7 @@ private:
protected:
std::string mName;
LLCondition* mRunCondition;
+ LLMutex* mDataLock;
apr_thread_t *mAPRThreadp;
apr_pool_t *mAPRPoolp;
@@ -122,15 +128,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 +211,12 @@ private:
void LLThread::lockData()
{
- mRunCondition->lock();
+ mDataLock->lock();
}
void LLThread::unlockData()
{
- mRunCondition->unlock();
+ mDataLock->unlock();
}
@@ -227,15 +233,27 @@ 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)
+ {
+ if (sMutex)
+ {
+ sMutex->lock();
+ }
+ mRef = 0;
+ if (sMutex)
+ {
+ sMutex->unlock();
+ }
+ return *this;
+ }
+
+
void ref()
{
diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h
index 7510cc12ed..0b6862444e 100644
--- a/indra/llcommon/lltypeinfolookup.h
+++ b/indra/llcommon/lltypeinfolookup.h
@@ -12,10 +12,50 @@
#if ! defined(LL_LLTYPEINFOLOOKUP_H)
#define LL_LLTYPEINFOLOOKUP_H
-#include "llsortedvector.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,
@@ -23,88 +63,55 @@
* different load modules will produce different std::type_info*.
* LLTypeInfoLookup contains a workaround to address this issue.
*
- * Specifically, when we don't find the passed std::type_info*,
- * LLTypeInfoLookup performs a linear search over registered entries to
- * compare name() strings. Presuming that this succeeds, we cache the new
- * (previously unrecognized) std::type_info* to speed future lookups.
- *
- * This worst-case fallback search (linear search with string comparison)
- * should only happen the first time we look up a given type from a particular
- * load module other than the one from which we initially registered types.
- * (However, a lookup which wouldn't succeed anyway will always have
- * worst-case performance.) This class is probably best used with less than a
- * few dozen different types.
+ * 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 LLTypeInfoLookup<VALUE> self;
- typedef LLSortedVector<const std::type_info*, VALUE> vector_type;
- typedef typename vector_type::key_type key_type;
- typedef typename vector_type::mapped_type mapped_type;
- typedef typename vector_type::value_type value_type;
- typedef typename vector_type::iterator iterator;
- typedef typename vector_type::const_iterator const_iterator;
+ typedef VALUE value_type;
LLTypeInfoLookup() {}
- 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(); }
-
- std::pair<iterator, bool> insert(const std::type_info* key, const VALUE& value)
- {
- return insert(value_type(key, value));
- }
-
- std::pair<iterator, bool> insert(const value_type& pair)
- {
- return mVector.insert(pair);
- }
+ bool empty() const { return mMap.empty(); }
+ std::size_t size() const { return mMap.size(); }
- // const find() forwards to non-const find(): this can alter mVector!
- const_iterator find(const std::type_info* key) const
+ template <typename KEY>
+ bool insert(const value_type& value)
{
- return const_cast<self*>(this)->find(key);
+ // 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;
}
- // non-const find() caches previously-unknown type_info* to speed future
- // lookups.
- iterator find(const std::type_info* key)
+ template <typename KEY>
+ boost::optional<value_type> find() const
{
- iterator found = mVector.find(key);
- if (found != mVector.end())
- {
- // If LLSortedVector::find() found, great, we're done.
- return found;
- }
- // Here we didn't find the passed type_info*. On Linux, though, even
- // for the same type, typeid(sametype) produces a different type_info*
- // when used in different load modules. So the fact that we didn't
- // find the type_info* we seek doesn't mean this type isn't
- // registered. Scan for matching name() string.
- for (typename vector_type::iterator ti(mVector.begin()), tend(mVector.end());
- ti != tend; ++ti)
- {
- if (std::string(ti->first->name()) == key->name())
- {
- // This unrecognized 'key' is for the same type as ti->first.
- // To speed future lookups, insert a new entry that lets us
- // look up ti->second using this same 'key'.
- return insert(key, ti->second).first;
- }
- }
- // We simply have never seen a type with this type_info* from any load
- // module.
- return mVector.end();
+ // 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:
- vector_type mVector;
+ impl_map_type mMap;
};
#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp
index b39ea0c6f2..21456a599b 100644
--- 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)
{
@@ -317,7 +319,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 +344,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/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 5d452ac4e4..db8c9c85ab 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -922,3 +922,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..0b9e7d0cd0 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -129,177 +129,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 +158,5 @@ public:
};
#endif
+
+
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index bfb30f900f..8585af0a29 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,8 +28,8 @@
#define LL_LLVERSIONVIEWER_H
const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 3;
-const S32 LL_VERSION_PATCH = 3;
+const S32 LL_VERSION_MINOR = 4;
+const S32 LL_VERSION_PATCH = 4;
const S32 LL_VERSION_BUILD = 0;
const char * const LL_CHANNEL = "Second Life Developer";
diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp
index 05289881d0..4c3bc674af 100644
--- a/indra/llcommon/tests/bitpack_test.cpp
+++ b/indra/llcommon/tests/bitpack_test.cpp
@@ -95,6 +95,7 @@ namespace tut
ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]);
unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4);
+ ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize);
}
// U32 packing
diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp
index f6d4221256..4c64f15ca7 100644
--- 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
--- 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/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
new file mode 100644
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 100644
index 0000000000..14f744a9f1
--- /dev/null
+++ b/indra/llcorehttp/_httpinternal.h
@@ -0,0 +1,154 @@
+/**
+ * @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.
+
+// Compatibility controls
+const bool HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX = true;
+
+} // end namespace LLCore
+
+#endif // _LLCORE_HTTP_INTERNAL_H_
diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..7db19b1841
--- /dev/null
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -0,0 +1,906 @@
+/**
+ * @file _httpoprequest.cpp
+ * @brief Definitions for internal class HttpOpRequest
+ *
+ * $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 "_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. Verify that what it says
+ // is consistent with the received data.
+ if (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 = curl_easy_init();
+ curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
+ curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
+
+ if (HTTP_ENABLE_LINKSYS_WRT54G_V5_DNS_FIX)
+ {
+ // 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.
+ curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15);
+ }
+ else
+ {
+ // *TODO: Revisit this old DNS timeout setting - may no longer be valid
+ // I don't think this is valid anymore, the Multi shared DNS
+ // cache is working well. For the case of naked easy handles,
+ // consider using a shared DNS object.
+ curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
+ }
+ curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
+ curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
+ curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, this);
+ curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, 1);
+ curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, 0);
+
+ 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)
+ {
+ LL_WARNS("HttpCore") << "Request body position beyond body size. Aborting request."
+ << 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);
+ 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, 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, 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, 2 * len, true, safe_line); // Goes out as one line
+ 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, 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, 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 100644
index 0000000000..7b65d17783
--- /dev/null
+++ b/indra/llcorehttp/_httpoprequest.h
@@ -0,0 +1,219 @@
+/**
+ * @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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..76c1e22431
--- /dev/null
+++ b/indra/llcorehttp/_httppolicy.cpp
@@ -0,0 +1,387 @@
+/**
+ * @file _httppolicy.cpp
+ * @brief Internal definitions of the Http policy 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 "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)
+{
+ 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);
+
+ // Retry or finalize
+ if (! op->mStatus)
+ {
+ // If this failed, we might want to retry. Have to inspect
+ // the status a little more deeply for those reasons worth retrying...
+ if (op->mPolicyRetries < op->mPolicyRetryLimit &&
+ ((op->mStatus.isHttpStatus() && op->mStatus.mType >= 499 && op->mStatus.mType <= 599) ||
+ cant_connect == op->mStatus ||
+ cant_res_proxy == op->mStatus ||
+ cant_res_host == op->mStatus ||
+ send_error == op->mStatus ||
+ recv_error == op->mStatus ||
+ upload_failed == op->mStatus ||
+ op_timedout == op->mStatus ||
+ post_error == op->mStatus))
+ {
+ // Okay, worth a retry. We include 499 in this test as
+ // it's the old 'who knows?' error from many grid services...
+ 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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..f2fcbf77a3
--- /dev/null
+++ b/indra/llcorehttp/httpcommon.cpp
@@ -0,0 +1,179 @@
+/**
+ * @file httpcommon.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 "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" },
+ { 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");
+}
+
+} // end namespace LLCore
+
diff --git a/indra/llcorehttp/httpcommon.h b/indra/llcorehttp/httpcommon.h
new file mode 100644
index 0000000000..c0d4ec5aad
--- /dev/null
+++ b/indra/llcorehttp/httpcommon.h
@@ -0,0 +1,311 @@
+/**
+ * @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, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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);
+ }
+
+}; // 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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..4a481db6ac
--- /dev/null
+++ b/indra/llcorehttp/httpresponse.h
@@ -0,0 +1,161 @@
+/**
+ * @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
+/// and return from the handler callback. Instances are refcounted
+/// and callers can bump the count and retain the object as needed.
+///
+/// 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.
+ 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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..e5488cf941
--- /dev/null
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -0,0 +1,2670 @@
+/**
+ * @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, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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;
+
+
+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(20);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 100;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(20);
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(100000);
+ }
+ 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 = 100;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req1->update(1000000);
+ req2->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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(50); // With one retry, should fail quickish
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 100;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(50); // With one retry, should fail quickish
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 100;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 3)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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(10);
+ while (count++ < limit && mHandlerCalls < 1)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && mHandlerCalls < 2)
+ {
+ req->update(1000000);
+ usleep(100000);
+ }
+ 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 = 10;
+ while (count++ < limit && ! HttpService::isStopped())
+ {
+ usleep(100000);
+ }
+ 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;
+ }
+}
+
+
+} // 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 100644
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 100644
index 0000000000..f7b542d3b5
--- /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, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * 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 error 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 error 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 error 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 100644
index 0000000000..75a3c39ef2
--- /dev/null
+++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py
@@ -0,0 +1,190 @@
+#!/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, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+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
+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.
+ """
+ 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.
+ self.answer(dict(reply="success", status=200,
+ reason="Your GET operation worked"))
+
+ def do_POST(self):
+ # Read the provided POST data.
+ # self.answer(self.read())
+ self.answer(dict(reply="success", status=200,
+ reason=self.read()))
+
+ def do_PUT(self):
+ # Read the provided PUT data.
+ # self.answer(self.read())
+ self.answer(dict(reply="success", status=200,
+ reason=self.read()))
+
+ 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" 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)
+ 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)
+ else: # 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
+ # 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()
+
+ 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
+
+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 100644
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 100644
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/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index d6dcde4b9f..34e25a8a71 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -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/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 6775b005f4..916c346b7a 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -292,11 +292,16 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 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);
}
@@ -1660,6 +1665,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 46e6d1a901..5f54585005 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -148,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);
@@ -189,7 +189,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);
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 452aad25cb..452aad25cb 100644..100755
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 433076c7a9..a871bcbb25 100644
--- 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;
@@ -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)
{
@@ -622,34 +588,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 +634,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 +725,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 +1185,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..499f690e76 100644
--- 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;
@@ -247,8 +247,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 +308,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 +351,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; }
@@ -651,8 +646,6 @@ protected:
U8 mMediaLoop;
std::string mMediaCurrentURL;
LLUUID mMediaID;
- U8 mMediaURLFilterEnable;
- LLSD mMediaURLFilterList;
U8 mMediaAllowNavigate;
U8 mMediaPreventCameraZoom;
F32 mMediaURLTimeout;
diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp
index cf88de12b4..0c0a844b73 100644
--- a/indra/llkdu/llimagej2ckdu.cpp
+++ b/indra/llkdu/llimagej2ckdu.cpp
@@ -1179,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);
@@ -1223,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 9ab0b9e4a7..fb1f6535ba 100644
--- 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"
diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h
index 9d923fc367..dbdf88b2d9 100644
--- 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 beee99a522..b675153b2e 100644..100755
--- a/indra/llkdu/tests/llimagej2ckdu_test.cpp
+++ b/indra/llkdu/tests/llimagej2ckdu_test.cpp
@@ -127,7 +127,6 @@ 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; }
int kdu_resolution::get_valid_band_indices(int &) { return 1; }
-kdu_decoder::kdu_decoder(kdu_subband , kdu_sample_allocator*, bool , float, int, kdu_thread_env*, kdu_thread_queue*) { }
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() { }
@@ -153,7 +152,6 @@ 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 ) { }
@@ -175,7 +173,7 @@ kdu_block* kdu_subband::open_block(kdu_coords, int*, kdu_thread_env*) { return N
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 ) { }
@@ -184,6 +182,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..5865ae030c 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -117,6 +117,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/llcamera.h b/indra/llmath/llcamera.h
index ec67b91d05..0b591be622 100644
--- 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
{
@@ -108,7 +108,7 @@ public:
};
private:
- LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+ LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
U8 mPlaneMask[8]; // 8 for alignment
F32 mView; // angle between top and bottom frustum planes in radians.
@@ -116,13 +116,13 @@ private:
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
F32 mNearPlane;
F32 mFarPlane;
- LLPlane mLocalPlanes[4];
+ LL_ALIGN_16(LLPlane mLocalPlanes[4]);
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
@@ -208,7 +208,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/llmath.h b/indra/llmath/llmath.h
index 9297bcbac2..b93f89d674 100644
--- 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.h b/indra/llmath/llmatrix3a.h
index adb7e3389d..9916cfd2da 100644
--- 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/llmatrix4a.h b/indra/llmath/llmatrix4a.h
index 27cf5b79f6..c4cefdb4fa 100644
--- 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()
{
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 1b11e83b4a..4ac1e55cfc 100644
--- 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;
+ 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/llplane.h b/indra/llmath/llplane.h
index a611894721..3c32441b11 100644
--- 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/llsimdmath.h b/indra/llmath/llsimdmath.h
index c7cdf7b32c..01458521ec 100644
--- a/indra/llmath/llsimdmath.h
+++ b/indra/llmath/llsimdmath.h
@@ -67,11 +67,10 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
#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.inl b/indra/llmath/llsimdtypes.inl
index 712239e425..e905c84954 100644
--- 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/llvector4a.cpp b/indra/llmath/llvector4a.cpp
index b66b7a7076..6edeb0fefe 100644
--- a/indra/llmath/llvector4a.cpp
+++ b/indra/llmath/llvector4a.cpp
@@ -24,6 +24,7 @@
* $/LicenseInfo$
*/
+#include "llmemory.h"
#include "llmath.h"
#include "llquantize.h"
@@ -44,7 +45,10 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast<const LLVector4a&> ( F
assert(dst != NULL);
assert(bytes > 0);
assert((bytes % sizeof(F32))== 0);
-
+ ll_assert_aligned(src,16);
+ ll_assert_aligned(dst,16);
+ assert(bytes%16==0);
+
F32* end = dst + (bytes / sizeof(F32) );
if (bytes > 64)
@@ -189,6 +193,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..0526793d3a 100644
--- 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
@@ -46,6 +47,7 @@ class LLRotation;
// LLVector3/LLVector4.
/////////////////////////////////
+LL_ALIGN_PREFIX(16)
class LLVector4a
{
public:
@@ -82,6 +84,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 +93,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)
@@ -313,7 +317,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..7c52ffef21 100644
--- a/indra/llmath/llvector4a.inl
+++ b/indra/llmath/llvector4a.inl
@@ -475,6 +475,7 @@ inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F3
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
--- 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..85ea14f9bc 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -95,17 +95,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);
@@ -328,16 +317,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 +341,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);
@@ -6962,14 +6951,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts)
if (num_verts)
{
mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- assert_aligned(mPositions, 16);
+ ll_assert_aligned(mPositions, 16);
mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
- assert_aligned(mNormals, 16);
+ ll_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);
+ ll_assert_aligned(mTexCoords, 16);
}
else
{
@@ -6990,17 +6979,21 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con
{
S32 new_verts = mNumVertices+1;
S32 new_size = new_verts*16;
-// S32 old_size = mNumVertices*16;
+ S32 old_size = mNumVertices*16;
//positions
- mPositions = (LLVector4a*) realloc(mPositions, new_size);
+ mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size, old_size);
+ ll_assert_aligned(mPositions,16);
//normals
- mNormals = (LLVector4a*) realloc(mNormals, new_size);
-
+ mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size, old_size);
+ ll_assert_aligned(mNormals,16);
+
//tex coords
new_size = ((new_verts*8)+0xF) & ~0xF;
- mTexCoords = (LLVector2*) realloc(mTexCoords, new_size);
+ old_size = ((mNumVertices*8)+0xF) & ~0xF;
+ mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size, old_size);
+ ll_assert_aligned(mTexCoords,16);
//just clear binormals
@@ -7053,7 +7046,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;
@@ -7094,12 +7088,12 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat
}
//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);
+ mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
+ ll_assert_aligned(mPositions, 16);
+ mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a), mNumVertices*sizeof(LLVector4a));
+ ll_assert_aligned(mNormals, 16);
+ mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF, (mNumVertices*sizeof(LLVector2)+0xF) & ~0xF);
+ ll_assert_aligned(mTexCoords, 16);
mNumVertices = new_count;
@@ -7145,7 +7139,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;
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 76cf9de613..2e6f9e2f71 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -54,6 +54,7 @@ class LLVolumeTriangle;
#include "llstrider.h"
#include "v4coloru.h"
#include "llrefcount.h"
+#include "llpointer.h"
#include "llfile.h"
//============================================================================
@@ -919,6 +920,10 @@ public:
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
diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp
index b5a935c2b5..cc83cb7235 100644
--- a/indra/llmath/llvolumeoctree.cpp
+++ b/indra/llmath/llvolumeoctree.cpp
@@ -131,7 +131,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;
@@ -236,8 +236,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..9ae34a0c4e 100644
--- 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>
diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp
new file mode 100644
index 0000000000..9105b1c1fd
--- /dev/null
+++ b/indra/llmath/tests/alignment_test.cpp
@@ -0,0 +1,139 @@
+/**
+ * @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];
+ 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));
+ }
+}
+
+}
diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h
index 56cb2ae73e..daf3a6857b 100644
--- 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/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 97f2792686..a6e2c89ba4 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -87,6 +87,9 @@ namespace LLAvatarNameCache
/// 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
//-----------------------------------------------------------------------
@@ -274,7 +277,7 @@ 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));
@@ -287,13 +290,14 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
// Clear this agent from the pending list
LLAvatarNameCache::sPendingQueue.erase(agent_id);
- const LLAvatarName& av_name = existing->second;
+ 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;
+ av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
}
}
@@ -330,8 +334,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 +344,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,27 +372,17 @@ 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,
@@ -402,20 +399,25 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
<< 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);
+ // Add to cache, because if we don't we'll keep rerequesting the
+ // same record forever. buildLegacyName should always guarantee
+ // that these records expire reasonably soon
+ // (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
+ // to something temporary we will eventually request and get the right data.
+ processName(agent_id, av_name, true);
}
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.
@@ -427,10 +429,6 @@ void LLAvatarNameCache::requestNamesViaLegacy()
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)
@@ -507,11 +505,11 @@ 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())
{
@@ -526,6 +524,12 @@ void LLAvatarNameCache::idle()
}
}
+ 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,8 +563,7 @@ 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
+ LL_DEBUGS("AvNameCache") << it->first
<< " user '" << av_name.mUsername << "' "
<< "expired " << now - av_name.mExpires << " secs ago"
<< LL_ENDL;
@@ -583,7 +586,7 @@ void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
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
+ av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
<< full_name
<< LL_ENDL;
@@ -651,8 +654,10 @@ 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
@@ -668,7 +673,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
{
// ...name already exists in cache, fire callback now
fireSignal(agent_id, slot, av_name);
- return;
+ return connection;
}
}
}
@@ -681,7 +686,7 @@ void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot)
LLAvatarName av_name;
buildLegacyName(full_name, &av_name);
fireSignal(agent_id, slot, av_name);
- return;
+ return connection;
}
}
}
@@ -698,15 +703,17 @@ 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;
}
@@ -733,12 +740,6 @@ 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..79f170f7c8 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -71,10 +71,11 @@ 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);
+ callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
// Allow display names to be explicitly disabled for testing.
void setUseDisplayNames(bool use);
@@ -85,10 +86,6 @@ namespace LLAvatarNameCache
/// 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,
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 5ea9b58300..8ffa8e4271 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -133,12 +133,12 @@ std::string LLCurl::getVersionString()
//////////////////////////////////////////////////////////////////////////////
LLCurl::Responder::Responder()
- : mReferenceCount(0)
{
}
LLCurl::Responder::~Responder()
{
+ LL_CHECK_MEMORY
}
// virtual
@@ -202,23 +202,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 +250,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 +294,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 +306,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 +484,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);
@@ -599,35 +590,50 @@ void LLCurl::Multi::cleanup(bool deleted)
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 ;
+
+ LL_CHECK_MEMORY
+
delete mEasyMutexp ;
mEasyMutexp = NULL ;
+ LL_CHECK_MEMORY
+
mQueued = 0 ;
mState = STATE_COMPLETED;
@@ -935,8 +941,8 @@ bool LLCurlThread::CurlRequest::processRequest()
if(!completed)
{
- setPriority(LLQueuedThread::PRIORITY_LOW) ;
- }
+ setPriority(LLQueuedThread::PRIORITY_LOW) ;
+ }
}
return completed ;
@@ -946,7 +952,7 @@ void LLCurlThread::CurlRequest::finishRequest(bool completed)
{
if(mMulti->isDead())
{
- mCurlThread->deleteMulti(mMulti) ;
+ mCurlThread->deleteMulti(mMulti) ;
}
else
{
@@ -990,6 +996,7 @@ void LLCurlThread::killMulti(LLCurl::Multi* multi)
return ;
}
+
multi->markDead() ;
}
@@ -1095,12 +1102,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)
{
@@ -1113,6 +1123,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;
@@ -1123,6 +1138,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)
{
@@ -1150,6 +1166,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)
{
@@ -1238,6 +1255,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
@@ -1504,29 +1723,42 @@ 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 ;
+ LL_CHECK_MEMORY
+
// removed as per https://jira.secondlife.com/browse/SH-3115
//llassert(Easy::sActiveHandles.empty());
}
@@ -1534,6 +1766,8 @@ void LLCurl::cleanupClass()
//static
CURLM* LLCurl::newMultiHandle()
{
+ llassert(sNotQuitting);
+
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
@@ -1567,6 +1801,7 @@ CURLMcode LLCurl::deleteMultiHandle(CURLM* handle)
//static
CURL* LLCurl::newEasyHandle()
{
+ llassert(sNotQuitting);
LLMutexLock lock(sHandleMutexp) ;
if(sTotalHandles + 1 > sMaxHandles)
@@ -1591,7 +1826,9 @@ void LLCurl::deleteEasyHandle(CURL* handle)
if(handle)
{
LLMutexLock lock(sHandleMutexp) ;
+ LL_CHECK_MEMORY
curl_easy_cleanup(handle) ;
+ LL_CHECK_MEMORY
sTotalHandles-- ;
}
}
diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h
index d6a7714d4c..7bcf61e233 100644
--- 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"
+
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;
/**
@@ -378,12 +377,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
{
@@ -414,6 +407,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/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 612d765969..d6ed08055e 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -749,7 +749,7 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list
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)
+ for (; pending_iter != pending_end; ++pending_iter)
{
LLAssetRequest* req = *pending_iter;
// Look for this pending request in the running list.
diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp
index 3d8ca2ad9f..a6fccd2a56 100644
--- 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/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index a16f5c7bf0..f3f0007205 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -289,6 +289,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(
@@ -358,7 +360,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())
@@ -371,8 +372,6 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
{
CURLcode result;
- static LLFastTimer::DeclareTimer FTM_PROCESS_URL_REQUEST_GET_RESULT("Get Result");
-
bool newmsg = false;
{
LLFastTimer t(FTM_PROCESS_URL_REQUEST_GET_RESULT);
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index e71fb96540..d7658862da 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -943,7 +943,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 +998,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 +1046,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");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index dd2c2dbd64..da2b613f53 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -943,7 +943,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 +998,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 +1046,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;
diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp
index d84fe0a49f..9b298d0c04 100644
--- 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/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 843c3bcc4b..a2be307cc8 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -189,9 +189,9 @@ namespace tut
}
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()
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index dbd96673a1..0644d2638c 100644
--- 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/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 3fc54573a7..8183467dc5 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -15,7 +15,6 @@ include_directories(
if (DARWIN)
include(CMakeFindFrameworks)
- find_library(CARBON_LIBRARY Carbon)
find_library(COCOA_LIBRARY Cocoa)
endif (DARWIN)
@@ -68,7 +67,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
--- 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..a434739350 100644
--- 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() //SPATTERS give this a better name.
+{
+// 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
--- 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/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index 7d0e313ff3..e4d9de7eb6 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -7,12 +7,14 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLXML)
+include(LLPhysicsExtensions)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
)
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index cb32a510b8..28ed051c55 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1026,7 +1026,8 @@ void LLModel::setVolumeFaceData(
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
{
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 30532247ac..6dee192783 100644..100755
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -149,7 +149,8 @@ bool LLPrimitive::cleanupVolumeManager()
LLPrimitive::LLPrimitive()
: mTextureList(),
mNumTEs(0),
- mMiscFlags(0)
+ mMiscFlags(0),
+ mNumBumpmapTEs(0)
{
mPrimitiveCode = 0;
@@ -237,7 +238,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)
@@ -316,6 +320,7 @@ S32 LLPrimitive::setTERotation(const U8 index, const F32 r)
//===============================================================
S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump)
{
+ updateNumBumpmap(index, bump);
return mTextureList.setBumpShinyFullbright(index, bump);
}
@@ -326,11 +331,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);
}
@@ -1445,6 +1452,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..8dcaa8c740 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -421,7 +421,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 +436,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 +448,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/object_flags.h b/indra/llprimitive/object_flags.h
index 94c559d757..31dbd15ae0 100644
--- 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/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 5c13df9f81..516af93316 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES
llglslshader.cpp
llimagegl.cpp
llpostprocess.cpp
+ llrendernavprim.cpp
llrendersphere.cpp
llshadermgr.cpp
lltexture.cpp
@@ -59,6 +60,7 @@ set(llrender_HEADER_FILES
llimagegl.h
llpostprocess.h
llrender.h
+ llrendernavprim.h
llrendersphere.h
llshadermgr.h
lltexture.h
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index 45a3b18179..362452d837 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -81,7 +81,7 @@ void LLCubeMap::initGL()
{
U32 texname = 0;
- LLImageGL::generateTextures(1, &texname);
+ LLImageGL::generateTextures(LLTexUnit::TT_CUBE_MAP, GL_RGB8, 1, &texname);
for (int i = 0; i < 6; i++)
{
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index fccbf37a8d..647512eb2e 100644
--- 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);
@@ -779,7 +789,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 +800,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
--- 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..b5bdba996f 100644
--- 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;
}
diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h
index 8b06191c56..059248fbbd 100644
--- 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 628a8d6131..0b56b3889c 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -249,6 +249,12 @@ 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;
+
//GL_ARB_debug_output
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB = NULL;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB = NULL;
@@ -421,6 +427,7 @@ LLGLManager::LLGLManager() :
mHasDrawBuffers(FALSE),
mHasTextureRectangle(FALSE),
mHasTextureMultisample(FALSE),
+ mHasTransformFeedback(FALSE),
mMaxSampleMaskWords(0),
mMaxColorTextureSamples(0),
mMaxDepthTextureSamples(0),
@@ -558,7 +565,8 @@ bool LLGLManager::initGL()
parse_gl_version( &mDriverVersionMajor,
&mDriverVersionMinor,
&mDriverVersionRelease,
- &mDriverVersionVendorString );
+ &mDriverVersionVendorString,
+ &mGLVersionString);
mGLVersion = mDriverVersionMajor + mDriverVersionMinor * .1f;
@@ -938,7 +946,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");
@@ -963,11 +970,14 @@ void LLGLManager::initExtensions()
ExtensionExists("GL_EXT_packed_depth_stencil", 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
@@ -1207,7 +1217,14 @@ 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");
+ }
if (mHasDebugOutput)
{
glDebugMessageControlARB = (PFNGLDEBUGMESSAGECONTROLARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageControlARB");
@@ -1964,6 +1981,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;
}
@@ -2052,7 +2070,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>]
@@ -2068,6 +2086,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;
@@ -2429,3 +2449,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..d70e764769 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -104,6 +104,7 @@ public:
BOOL mHasDepthClamp;
BOOL mHasTextureRectangle;
BOOL mHasTextureMultisample;
+ BOOL mHasTransformFeedback;
S32 mMaxSampleMaskWords;
S32 mMaxColorTextureSamples;
S32 mMaxDepthTextureSamples;
@@ -141,6 +142,7 @@ public:
S32 mGLSLVersionMajor;
S32 mGLSLVersionMinor;
std::string mDriverVersionVendorString;
+ std::string mGLVersionString;
S32 mVRAM; // VRAM in MB
S32 mGLMaxVertexRange;
@@ -417,13 +419,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/llglheaders.h b/indra/llrender/llglheaders.h
index d61ec707f0..509de51f4d 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -528,6 +528,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;
+
+
#elif LL_WINDOWS
//----------------------------------------------------------------------------
// LL_WINDOWS
@@ -759,6 +766,12 @@ 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;
+
//GL_ARB_debug_output
extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB;
extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB;
@@ -980,7 +993,12 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
}
#endif
+#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1070
+#include <OpenGL/gl.h>
+#else
#include <AGL/gl.h>
+#endif
+
#endif // LL_MESA / LL_WINDOWS / LL_DARWIN
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 4b7e639aed..7cbf39096e 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -129,7 +129,9 @@ void LLGLSLShader::unload()
}
BOOL LLGLSLShader::createShader(vector<string> * attributes,
- vector<string> * uniforms)
+ vector<string> * uniforms,
+ U32 varying_count,
+ const char** varyings)
{
//reloading, reset matrix hash values
for (U32 i = 0; i < LLRender::NUM_MATRIX_MODES; ++i)
@@ -172,6 +174,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)
{
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 7873fe3c4e..5c68cb46eb 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -76,7 +76,9 @@ public:
void unload();
BOOL createShader(std::vector<std::string> * attributes,
- std::vector<std::string> * uniforms);
+ std::vector<std::string> * 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);
diff --git a/indra/llrender/llglstates.h b/indra/llrender/llglstates.h
index e26aead676..0e2c3bcb44 100644
--- 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/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index c04a3f6b41..a4d7872ec2 100644..100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -42,6 +42,10 @@
//----------------------------------------------------------------------------
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
U32 LLImageGL::sUniqueCount = 0;
@@ -50,7 +54,8 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0;
S32 LLImageGL::sBoundTextureMemoryInBytes = 0;
S32 LLImageGL::sCurBoundTextureMemory = 0;
S32 LLImageGL::sCount = 0;
-std::list<U32> LLImageGL::sDeadTextureList;
+LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
+U32 LLImageGL::sCurTexName = 1;
BOOL LLImageGL::sGlobalUseAnisotropic = FALSE;
F32 LLImageGL::sLastFrameTime = 0.f;
@@ -232,9 +237,11 @@ 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;
@@ -416,6 +423,7 @@ void LLImageGL::init(BOOL usemipmaps)
mTarget = GL_TEXTURE_2D;
mBindTarget = LLTexUnit::TT_TEXTURE;
mHasMipMaps = false;
+ mMipLevels = -1;
mIsResident = 0;
@@ -470,7 +478,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)
{
@@ -503,6 +511,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
{
@@ -606,8 +619,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
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)
@@ -620,6 +649,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
@@ -662,10 +694,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);
@@ -679,6 +707,11 @@ 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
+ glTexParameteri(mTarget, GL_GENERATE_MIPMAP, GL_TRUE);
+
LLImageGL::setManualImage(mTarget, 0, mFormatInternal,
w, h,
mFormatPrimary, mFormatType,
@@ -694,16 +727,10 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
stop_glerror();
}
}
-
- if (gGLManager.mHasFramebufferObject)
- {
- glGenerateMipmap(LLTexUnit::getInternalType(mBindTarget));
- }
}
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);
@@ -713,6 +740,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
const U8* cur_mip_data = 0;
S32 prev_mip_size = 0;
S32 cur_mip_size = 0;
+
+ mMipLevels = nummips;
+
for (int m=0; m<nummips; m++)
{
if (m==0)
@@ -777,10 +807,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)
@@ -812,7 +842,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
}
}
- mHasMipMaps = false;
}
stop_glerror();
mGLTextureCreated = true;
@@ -836,14 +865,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 )
{
@@ -1025,23 +1053,65 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
}
// static
-void LLImageGL::generateTextures(S32 numTextures, U32 *textures)
+void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
{
- glGenTextures(numTextures, (GLuint*)textures);
+ bool empty = true;
+
+ dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
+
+ if (iter != sDeadTextureList[type].end())
+ {
+ empty = iter->second.empty();
+ }
+
+ for (S32 i = 0; i < numTextures; ++i)
+ {
+ if (!empty)
+ {
+ textures[i] = iter->second.front();
+ iter->second.pop_front();
+ empty = iter->second.empty();
+ }
+ else
+ {
+ textures[i] = sCurTexName++;
+ }
+ }
}
// static
-void LLImageGL::deleteTextures(S32 numTextures, U32 *textures, bool immediate)
+void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate)
{
- for (S32 i = 0; i < numTextures; i++)
+ if (gGLManager.mInited)
{
- sDeadTextureList.push_back(textures[i]);
- }
+ if (format == 0 || type == LLTexUnit::TT_CUBE_MAP || mip_levels == -1)
+ { //unknown internal format or unknown number of mip levels, not safe to reuse
+ glDeleteTextures(numTextures, textures);
+ }
+ else
+ {
+ for (S32 i = 0; i < numTextures; ++i)
+ { //remove texture from VRAM by setting its size to zero
+ for (S32 j = 0; j <= mip_levels; j++)
+ {
+ gGL.getTexUnit(0)->bindManual(type, textures[i]);
+
+ glTexImage2D(LLTexUnit::getInternalType(type), j, format, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+
+ llassert(std::find(sDeadTextureList[type][format].begin(),
+ sDeadTextureList[type][format].end(), textures[i]) ==
+ sDeadTextureList[type][format].end());
- if (immediate)
+ sDeadTextureList[type][format].push_back(textures[i]);
+ }
+ }
+ }
+
+ /*if (immediate)
{
LLImageGL::deleteDeadTextures();
- }
+ }*/
}
// static
@@ -1166,10 +1236,11 @@ BOOL LLImageGL::createGLTexture()
if(mTexName)
{
- glDeleteTextures(1, (reinterpret_cast<GLuint*>(&mTexName))) ;
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, (reinterpret_cast<GLuint*>(&mTexName))) ;
}
- glGenTextures(1, (GLuint*)&mTexName);
+
+ LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
stop_glerror();
if (!mTexName)
{
@@ -1197,8 +1268,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() ;
@@ -1206,7 +1276,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 )
{
@@ -1282,7 +1352,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
}
else
{
- LLImageGL::generateTextures(1, &mTexName);
+ LLImageGL::generateTextures(mBindTarget, mFormatInternal, 1, &mTexName);
stop_glerror();
{
llverify(gGL.getTexUnit(0)->bind(this));
@@ -1327,7 +1397,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
{
sGlobalTextureMemoryInBytes -= mTextureMemory;
- LLImageGL::deleteTextures(1, &old_name);
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &old_name);
stop_glerror();
}
@@ -1456,7 +1526,7 @@ void LLImageGL::deleteDeadTextures()
{
bool reset = false;
- while (!sDeadTextureList.empty())
+ /*while (!sDeadTextureList.empty())
{
GLuint tex = sDeadTextureList.front();
sDeadTextureList.pop_front();
@@ -1478,7 +1548,7 @@ void LLImageGL::deleteDeadTextures()
glDeleteTextures(1, &tex);
stop_glerror();
- }
+ }*/
if (reset)
{
@@ -1496,7 +1566,7 @@ void LLImageGL::destroyGLTexture()
mTextureMemory = 0;
}
- LLImageGL::deleteTextures(1, &mTexName);
+ LLImageGL::deleteTextures(mBindTarget, mFormatInternal, mMipLevels, 1, &mTexName);
mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel.
mTexName = 0;
mGLTextureCreated = FALSE ;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index f34b9fa91a..cf3c484c79 100644..100755
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -45,8 +45,16 @@ class LLImageGL : public LLRefCount
{
friend class LLTexUnit;
public:
- static std::list<U32> sDeadTextureList;
+ static U32 sCurTexName;
+ //previously used but now available texture names
+ // sDeadTextureList[<usage>][<internal format>]
+ typedef std::map<U32, std::list<U32> > dead_texturelist_t;
+ static dead_texturelist_t sDeadTextureList[LLTexUnit::TT_NONE];
+
+ // These 2 functions replace glGenTextures() and glDeleteTextures()
+ static void generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures);
+ static void deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip_levels, S32 numTextures, U32 *textures, bool immediate = false);
static void deleteDeadTextures();
// Size calculation
@@ -92,14 +100,10 @@ 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, bool allow_compression = true);
BOOL createGLTexture() ;
@@ -217,7 +221,8 @@ 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;
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 93bac4c779..4597d06260 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -408,12 +408,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)
{
@@ -464,11 +466,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)
@@ -632,7 +648,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)
@@ -1421,6 +1437,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();
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index fa5f7f311d..78a310e525 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -346,6 +346,7 @@ public:
void loadIdentity();
void multMatrix(const GLfloat* m);
void matrixMode(U32 mode);
+ U32 getMatrixMode();
const glh::matrix4f& getModelviewMatrix();
const glh::matrix4f& getProjectionMatrix();
diff --git a/indra/llrender/llrendernavprim.cpp b/indra/llrender/llrendernavprim.cpp
new file mode 100644
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 100644
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/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 780f1dc484..c1b96a43da 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -51,12 +51,13 @@ void check_framebuffer_status()
}
bool LLRenderTarget::sUseFBO = false;
+U32 LLRenderTarget::sCurFBO = 0;
LLRenderTarget::LLRenderTarget() :
mResX(0),
mResY(0),
- mTex(0),
mFBO(0),
+ mPreviousFBO(0),
mDepth(0),
mStencil(0),
mUseDepth(false),
@@ -70,8 +71,47 @@ LLRenderTarget::~LLRenderTarget()
release();
}
+void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
+{
+ //for accounting, get the number of pixels added/subtracted
+ S32 pix_diff = (resx*resy)-(mResX*mResY);
+
+ mResX = resx;
+ mResY = resy;
+
+ for (U32 i = 0; i < mTex.size(); ++i)
+ { //resize color attachments
+ gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, 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) 4096);
+ resy = llmin(resy, (U32) 4096);
+
stop_glerror();
release();
stop_glerror();
@@ -111,7 +151,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,14 +168,23 @@ 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;
- LLImageGL::generateTextures(1, &tex);
+ LLImageGL::generateTextures(mUsage, color_fmt, 1, &tex);
gGL.getTexUnit(0)->bindManual(mUsage, tex);
stop_glerror();
@@ -189,10 +238,11 @@ 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 (gDebugGL)
{ //bind and unbind to validate target
@@ -217,7 +267,7 @@ bool LLRenderTarget::allocateDepth()
}
else
{
- LLImageGL::generateTextures(1, &mDepth);
+ LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
U32 internal_type = LLTexUnit::getInternalType(mUsage);
@@ -277,7 +327,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
check_framebuffer_status();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO);
target.mUseDepth = true;
}
@@ -294,7 +344,7 @@ void LLRenderTarget::release()
}
else
{
- LLImageGL::deleteTextures(1, &mDepth, true);
+ LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
stop_glerror();
}
mDepth = 0;
@@ -326,8 +376,9 @@ void LLRenderTarget::release()
if (mTex.size() > 0)
{
sBytesAllocated -= mResX*mResY*4*mTex.size();
- LLImageGL::deleteTextures(mTex.size(), &mTex[0], true);
+ LLImageGL::deleteTextures(mUsage, mInternalFormat[0], 0, mTex.size(), &mTex[0], true);
mTex.clear();
+ mInternalFormat.clear();
}
mResX = mResY = 0;
@@ -339,9 +390,13 @@ void LLRenderTarget::bindTarget()
{
if (mFBO)
{
+ mPreviousFBO = sCurFBO;
+
stop_glerror();
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
+ sCurFBO = mFBO;
+
stop_glerror();
if (gGLManager.mHasDrawBuffers)
{ //setup multiple render targets
@@ -367,16 +422,6 @@ void LLRenderTarget::bindTarget()
sBoundTarget = this;
}
-// static
-void LLRenderTarget::unbindTarget()
-{
- if (gGLManager.mHasFramebufferObject)
- {
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- sBoundTarget = NULL;
-}
-
void LLRenderTarget::clear(U32 mask_in)
{
U32 mask = GL_COLOR_BUFFER_BIT;
@@ -442,7 +487,8 @@ void LLRenderTarget::flush(bool fetch_depth)
else
{
stop_glerror();
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFBO);
+ sCurFBO = mPreviousFBO;
stop_glerror();
}
}
@@ -472,7 +518,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 +535,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();
}
}
@@ -515,7 +561,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();
}
}
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index 2735ab21c5..cf15f66d31 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -57,14 +57,13 @@
*/
-class LLMultisampleBuffer;
-
class LLRenderTarget
{
public:
//whether or not to use FBO implementation
static bool sUseFBO;
static U32 sBytesAllocated;
+ static U32 sCurFBO;
LLRenderTarget();
~LLRenderTarget();
@@ -74,6 +73,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, U32 color_fmt);
+
//add color buffer attachment
//limit of 4 color attachments per render target
bool addColorAttachment(U32 color_fmt);
@@ -92,9 +97,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);
@@ -142,7 +144,9 @@ protected:
U32 mResX;
U32 mResY;
std::vector<U32> mTex;
+ std::vector<U32> mInternalFormat;
U32 mFBO;
+ U32 mPreviousFBO;
U32 mDepth;
bool mStencil;
bool mUseDepth;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 5a6e6cab3e..b6a9a6b653 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -643,7 +643,7 @@ 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");
@@ -702,7 +702,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 +716,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
@@ -1026,6 +1039,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");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index f792faa8f0..7a16b7c20f 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -97,6 +97,8 @@ public:
LIGHT_CENTER,
LIGHT_SIZE,
LIGHT_FALLOFF,
+ BOX_CENTER,
+ BOX_SIZE,
GLOW_MIN_LUMINANCE,
GLOW_MAX_EXTRACT_ALPHA,
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 823c6b9dc5..2fe0aa0b72 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -38,12 +38,6 @@
#include "llglslshader.h"
#include "llmemory.h"
-#if LL_DARWIN
-#define LL_VBO_POOLING 1
-#else
-#define LL_VBO_POOLING 0
-#endif
-
//Next Highest Power Of Two
//helper function, returns first number > v that is a power of 2, or v if v is already a power of 2
U32 nhpo2(U32 v)
@@ -71,6 +65,7 @@ U32 wpo2(U32 i)
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?
@@ -83,6 +78,7 @@ 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);
//============================================================================
@@ -95,6 +91,11 @@ LLVBOPool LLVertexBuffer::sDynamicIBOPool(GL_DYNAMIC_DRAW_ARB, GL_ELEMENT_ARRAY_
U32 LLVBOPool::sBytesPooled = 0;
U32 LLVBOPool::sIndexBytesPooled = 0;
+U32 LLVBOPool::sCurGLName = 1;
+
+std::list<U32> LLVertexBuffer::sAvailableVAOName;
+U32 LLVertexBuffer::sCurVAOName = 1;
+
U32 LLVertexBuffer::sAllocatedIndexBytes = 0;
U32 LLVertexBuffer::sIndexCount = 0;
@@ -119,69 +120,55 @@ 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
-
- LLGLSyncFence()
- {
-#ifdef GL_ARB_sync
- mSync = 0;
-#endif
- }
+ U32 ret = 0;
- virtual ~LLGLSyncFence()
+ if (mGLNamePool.empty())
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
-#endif
+ ret = sCurGLName++;
}
-
- void placeFence()
+ else
{
-#ifdef GL_ARB_sync
- if (mSync)
- {
- glDeleteSync(mSync);
- }
- mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
+ ret = mGLNamePool.front();
+ mGLNamePool.pop_front();
}
- void wait()
+ return ret;
+}
+
+void LLVBOPool::deleteBuffer(U32 name)
+{
+ if (gGLManager.mInited)
{
-#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
- }
+ LLVertexBuffer::unbind();
+ glBindBufferARB(mType, name);
+ glBufferDataARB(mType, 0, NULL, mUsage);
-};
+ llassert(std::find(mGLNamePool.begin(), mGLNamePool.end(), name) == mGLNamePool.end());
+
+ mGLNamePool.push_back(name);
+
+ glBindBufferARB(mType, 0);
+ }
+}
-volatile U8* LLVBOPool::allocate(U32& name, U32 size)
+LLVBOPool::LLVBOPool(U32 vboUsage, U32 vboType)
+: mUsage(vboUsage), mType(vboType)
+{
+ mMissCount.resize(LL_VBO_POOL_SEED_COUNT);
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
+}
+
+volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed)
{
llassert(vbo_block_size(size) == size);
volatile U8* ret = NULL;
-#if LL_VBO_POOLING
-
U32 i = vbo_block_index(size);
if (mFreeList.size() <= i)
@@ -189,12 +176,18 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
mFreeList.resize(i+1);
}
- if (mFreeList[i].empty())
+ if (mFreeList[i].empty() || for_seed)
{
//make a new buffer
- glGenBuffersARB(1, &name);
+ name = genBuffer();
+
glBindBufferARB(mType, name);
+ if (!for_seed && i < LL_VBO_POOL_SEED_COUNT)
+ { //record this miss
+ mMissCount[i]++;
+ }
+
if (mType == GL_ARRAY_BUFFER_ARB)
{
LLVertexBuffer::sAllocatedBytes += size;
@@ -215,6 +208,25 @@ 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
{
@@ -232,33 +244,6 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size)
mFreeList[i].pop_front();
}
-#else //no pooling
-
- glGenBuffersARB(1, &name);
- glBindBufferARB(mType, name);
-
- 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);
- }
- else
- { //always use a true hint of static draw when allocating non-client-backed buffers
- glBufferDataARB(mType, size, 0, GL_STATIC_DRAW_ARB);
- }
-
- glBindBufferARB(mType, 0);
-
-#endif
return ret;
}
@@ -267,50 +252,48 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size)
{
llassert(vbo_block_size(size) == size);
-#if LL_VBO_POOLING
-
- U32 i = vbo_block_index(size);
-
- llassert(mFreeList.size() > i);
+ deleteBuffer(name);
+ ll_aligned_free_16((U8*) buffer);
- 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
{
- if (mType == GL_ARRAY_BUFFER_ARB)
- {
- sBytesPooled += size;
- }
- else
- {
- sIndexBytesPooled += size;
- }
- mFreeList[i].push_back(rec);
+ LLVertexBuffer::sAllocatedIndexBytes -= size;
}
-#else //no pooling
- glDeleteBuffersARB(1, &name);
- ll_aligned_free_16((U8*) buffer);
+}
- if (mType == GL_ARRAY_BUFFER_ARB)
+void LLVBOPool::seedPool()
+{
+ U32 dummy_name = 0;
+
+ if (mFreeList.size() < LL_VBO_POOL_SEED_COUNT)
{
- LLVertexBuffer::sAllocatedBytes -= size;
+ mFreeList.resize(LL_VBO_POOL_SEED_COUNT);
}
- else
+
+ for (U32 i = 0; i < LL_VBO_POOL_SEED_COUNT; i++)
{
- LLVertexBuffer::sAllocatedIndexBytes -= size;
+ 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);
+ }
+ }
}
-#endif
}
+
+
void LLVBOPool::cleanup()
{
- U32 size = 1;
+ U32 size = LL_VBO_BLOCK_SIZE;
for (U32 i = 0; i < mFreeList.size(); ++i)
{
@@ -320,8 +303,8 @@ void LLVBOPool::cleanup()
{
Record& r = l.front();
- glDeleteBuffersARB(1, &r.mGLName);
-
+ deleteBuffer(r.mGLName);
+
if (r.mClientData)
{
ll_aligned_free_16((void*) r.mClientData);
@@ -341,8 +324,11 @@ void LLVBOPool::cleanup()
}
}
- size *= 2;
+ size += LL_VBO_BLOCK_SIZE;
}
+
+ //reset miss counts
+ std::fill(mMissCount.begin(), mMissCount.end(), 0);
}
@@ -376,6 +362,41 @@ 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();
+ sStreamIBOPool.seedPool();
+ sDynamicIBOPool.seedPool();
+}
//static
void LLVertexBuffer::setupClientArrays(U32 data_mask)
@@ -534,8 +555,21 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
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();
@@ -985,7 +1019,7 @@ LLVertexBuffer::~LLVertexBuffer()
if (mGLArray)
{
#if GL_ARB_vertex_array_object
- glDeleteVertexArrays(1, &mGLArray);
+ releaseVAOName(mGLArray);
#endif
}
@@ -1211,10 +1245,10 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
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);
@@ -1270,7 +1304,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create)
if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO))
{
#if GL_ARB_vertex_array_object
- glGenVertexArrays(1, &mGLArray);
+ mGLArray = getVAOName();
#endif
setupVertexArray();
}
@@ -1306,7 +1340,7 @@ void LLVertexBuffer::setupVertexArray()
1, //TYPE_WEIGHT,
4, //TYPE_WEIGHT4,
4, //TYPE_CLOTHWEIGHT,
- 4, //TYPE_TEXTURE_INDEX
+ 1, //TYPE_TEXTURE_INDEX
};
U32 attrib_type[] =
@@ -1323,7 +1357,7 @@ void LLVertexBuffer::setupVertexArray()
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[] =
@@ -2140,6 +2174,16 @@ 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)
{
@@ -2291,10 +2335,10 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
stop_glerror();
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
- /*if ((data_mask & mTypeMask) != data_mask)
+ if (gDebugGL && ((data_mask & mTypeMask) != data_mask))
{
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
- }*/
+ }
if (LLGLSLShader::sNoFixedFunction)
{
@@ -2370,7 +2414,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)
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 7477dec3ad..11fa4ab6a0 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -57,23 +57,28 @@ public:
static U32 sBytesPooled;
static U32 sIndexBytesPooled;
- LLVBOPool(U32 vboUsage, U32 vboType)
- : mUsage(vboUsage)
- , mType(vboType)
- {}
+ static U32 sCurGLName;
+ 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:
@@ -81,17 +86,15 @@ public:
volatile U8* mClientData;
};
+ std::list<U32> mGLNamePool;
+
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;
@@ -125,13 +128,22 @@ public:
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);
@@ -208,7 +220,6 @@ protected:
void destroyGLIndices();
void updateNumVerts(S32 nverts);
void updateNumIndices(S32 nindices);
- bool useVBOs() const;
void unmapBuffer();
public:
@@ -218,6 +229,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
@@ -240,12 +253,14 @@ public:
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 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; }
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 20c3456a56..d92b6aa1c0 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -23,6 +23,7 @@ include_directories(
${LLWINDOW_INCLUDE_DIRS}
${LLVFS_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
+ ${LIBS_PREBUILD_DIR}/include/hunspell
)
set(llui_SOURCE_FILES
@@ -84,6 +85,7 @@ set(llui_SOURCE_FILES
llsearcheditor.cpp
llslider.cpp
llsliderctrl.cpp
+ llspellcheck.cpp
llspinctrl.cpp
llstatbar.cpp
llstatgraph.cpp
@@ -153,7 +155,6 @@ set(llui_HEADER_FILES
llflyoutbutton.h
llfocusmgr.h
llfunctorregistry.h
- llhandle.h
llhelp.h
lliconctrl.h
llkeywords.h
@@ -191,6 +192,8 @@ set(llui_HEADER_FILES
llscrolllistitem.h
llsliderctrl.h
llslider.h
+ llspellcheck.h
+ llspellcheckmenuhandler.h
llspinctrl.h
llstatbar.h
llstatgraph.h
@@ -260,6 +263,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/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 806d2ef3f6..41e5d74042 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -563,8 +563,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/llfloater.cpp b/indra/llui/llfloater.cpp
index 8ca1e685a9..054b9173d3 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -748,6 +748,10 @@ void LLFloater::closeFloater(bool app_quitting)
dependee->setFocus(TRUE);
}
}
+
+ // STORM-1879: since this floater has focus, treat the closeFloater- call
+ // like a click on the close-button, and close gear- and contextmenus
+ LLMenuGL::sMenuContainer->hideMenus();
}
dirtyRect();
@@ -3229,24 +3233,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 +3265,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..e64b6d04d3 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -202,7 +202,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 );
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 9115eb7174..306caf2b91 100644
--- 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;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index d0fbf4b913..48d49af588 100644
--- 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),
@@ -151,7 +157,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
mHighlightColor(p.highlight_color()),
mPreeditBgColor(p.preedit_bg_color()),
mGLFont(p.font),
- mContextMenuHandle()
+ mContextMenuHandle(),
+ mAutoreplaceCallback()
{
llassert( mMaxLengthBytes > 0 );
@@ -177,6 +184,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());
@@ -195,7 +208,6 @@ LLLineEditor::~LLLineEditor()
gFocusMgr.releaseFocusIfNeeded( this );
}
-
void LLLineEditor::onFocusReceived()
{
gEditMenuHandler = this;
@@ -519,6 +531,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)
{
@@ -866,6 +971,12 @@ void LLLineEditor::addChar(const llwchar uni_char)
LLUI::reportBadKeystroke();
}
+ if (!mReadOnly && mAutoreplaceCallback != NULL)
+ {
+ // call callback
+ mAutoreplaceCallback(mText, mCursorPos);
+ }
+
getWindow()->hideCursorUntilMouseMove();
}
@@ -1058,9 +1169,8 @@ void LLLineEditor::cut()
LLUI::reportBadKeystroke();
}
else
- if( mKeystrokeCallback )
{
- mKeystrokeCallback( this );
+ onKeystroke();
}
}
}
@@ -1187,9 +1297,8 @@ void LLLineEditor::pasteHelper(bool is_primary)
LLUI::reportBadKeystroke();
}
else
- if( mKeystrokeCallback )
{
- mKeystrokeCallback( this );
+ onKeystroke();
}
}
}
@@ -1442,9 +1551,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 +1607,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 +1640,7 @@ void LLLineEditor::doDelete()
if (!prevalidateInput(text_to_delete))
{
- if( mKeystrokeCallback )
- mKeystrokeCallback( this );
-
+ onKeystroke();
return;
}
setCursor(getCursor() + 1);
@@ -1549,10 +1656,9 @@ void LLLineEditor::doDelete()
}
else
{
- if( mKeystrokeCallback )
- {
- mKeystrokeCallback( this );
- }
+ onKeystroke();
+
+ mSpellCheckTimer.setTimerExpirySec(SPELLCHECK_DELAY);
}
}
}
@@ -1624,6 +1730,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 +1808,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 +1859,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 +1873,7 @@ void LLLineEditor::draw()
}
else
{
- mGLFont->render(
+ rendered_text = mGLFont->render(
mText, mScrollHPos,
rendered_pixels_right, text_bottom,
text_color,
@@ -1778,6 +1888,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())
{
@@ -2109,6 +2314,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 +2445,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
@@ -2386,7 +2599,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..71dd53f608 100644
--- 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);
@@ -169,6 +189,9 @@ public:
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
+ typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
+ autoreplace_callback_t mAutoreplaceCallback;
+ void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
const std::string& getLabel() { return mLabel.getString(); }
@@ -223,6 +246,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 +346,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/llmenugl.cpp b/indra/llui/llmenugl.cpp
index ff6928ffda..efb9848a90 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3854,7 +3854,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 +3908,14 @@ void LLContextMenu::show(S32 x, S32 y)
setRect(rect);
arrange();
+ if (spawning_view)
+ {
+ mSpawningViewHandle = spawning_view->getHandle();
+ }
+ else
+ {
+ mSpawningViewHandle.markDead();
+ }
LLView::setVisible(TRUE);
}
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 36f3ba34b9..67b3e1fbe6 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -670,7 +670,7 @@ public:
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 );
@@ -683,10 +683,14 @@ public:
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;
};
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 09480968a6..210a320f41 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1424,25 +1424,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;
}
@@ -1452,7 +1446,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;
}
@@ -1488,6 +1482,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);
@@ -1504,7 +1502,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;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 72973789db..b3b0bae862 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -121,6 +121,7 @@ struct LLNotificationTemplate
Optional<std::string> yes_text,
no_text,
cancel_text,
+ help_text,
ignore_text;
TemplateRef()
@@ -128,6 +129,7 @@ struct LLNotificationTemplate
yes_text("yestext"),
no_text("notext"),
cancel_text("canceltext"),
+ help_text("helptext"),
ignore_text("ignoretext")
{}
};
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 00318cec6b..67472ad166 100644
--- 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
--- 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/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 9b7e30bb04..2fd187a526 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -389,12 +389,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;
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index 07a6dfaa10..af124d9826 100644
--- 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
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b3e1b63db5..d332aa933e 100644
--- 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,6 +613,35 @@ void LLScrollListCtrl::calcColumnWidths()
LLScrollListColumn* column = *column_itor;
if (!column) continue;
+ if (mColumnWidthsDirty)
+ {
+ mColumnWidthsDirty = false;
+ // 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;
+ }
+
+ 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();
if (column->mRelWidth >= 0)
@@ -601,23 +653,13 @@ 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++)
+ if (column->getWidth() != new_width)
{
- LLScrollListCell* cellp = (*iter)->getColumn(column->mIndex);
- if (!cellp) continue;
-
- column->mMaxContentWidth = llmax(LLFontGL::getFontSansSerifSmall()->getWidth(cellp->getValue().asString()) + mColumnPadding + COLUMN_TEXT_PADDING, column->mMaxContentWidth);
+ column->setWidth(new_width);
+ width_changed = true;
}
-
- max_item_width += column->mMaxContentWidth;
}
-
- mMaxContentWidth = max_item_width;
+ return width_changed;
}
const S32 SCROLL_LIST_ROW_PAD = 2;
@@ -653,7 +695,12 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)
void LLScrollListCtrl::updateColumns()
{
- calcColumnWidths();
+ if (!mColumnsDirty)
+ return;
+
+ mColumnsDirty = false;
+
+ bool columns_changed_width = updateColumnWidths();
// update column headers
std::vector<LLScrollListColumn*>::iterator column_ordered_it;
@@ -702,20 +749,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)
{
- 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 +805,7 @@ BOOL LLScrollListCtrl::selectFirstItem()
{
deselectItem(itemp);
}
- first_item = FALSE;
+ first_item = false;
}
if (mCommitOnSelectionChange)
{
@@ -1390,17 +1439,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 +1519,6 @@ void LLScrollListCtrl::drawItems()
cur_y -= mLineHeight;
}
- line++;
}
}
}
@@ -1480,7 +1534,7 @@ void LLScrollListCtrl::draw()
if (mNeedsScroll)
{
scrollToShowSelected();
- mNeedsScroll = FALSE;
+ mNeedsScroll = false;
}
LLRect background(0, getRect().getHeight(), getRect().getWidth(), 0);
// Draw background
@@ -1491,11 +1545,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 +1753,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 +1771,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();
}
@@ -1789,7 +1839,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.getLegacyName();
}
LLUrlAction::copyURLToClipboard(name);
}
@@ -1843,7 +1895,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 +1924,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 +2030,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 +2077,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
{
// commit implicit in call
selectPrevItem(FALSE);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
handled = TRUE;
}
break;
@@ -2034,7 +2086,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
{
// commit implicit in call
selectNextItem(FALSE);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
handled = TRUE;
}
break;
@@ -2042,7 +2094,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 +2107,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 +2120,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectFirstItem();
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2081,7 +2133,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
if (mAllowKeyboardMovement || hasFocus())
{
selectNthItem(getItemCount() - 1);
- mNeedsScroll = TRUE;
+ mNeedsScroll = true;
if (mCommitOnKeyboardMovement
&& !mCommitOnSelectionChange)
{
@@ -2120,7 +2172,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 +2213,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 +2259,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 +2330,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
}
itemp->setSelected(TRUE);
mLastSelected = itemp;
- mSelectionChanged = TRUE;
+ mSelectionChanged = true;
}
}
@@ -2299,7 +2351,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
{
cellp->highlightText(0, 0);
}
- mSelectionChanged = TRUE;
+ mSelectionChanged = true;
}
}
@@ -2307,7 +2359,7 @@ void LLScrollListCtrl::commitIfChanged()
{
if (mSelectionChanged)
{
- mDirty = TRUE;
+ mDirty = true;
mSelectionChanged = FALSE;
onCommit();
}
@@ -2418,7 +2470,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 +2757,11 @@ BOOL LLScrollListCtrl::hasSortOrder() const
return !mSortColumns.empty();
}
+void LLScrollListCtrl::clearSortOrder()
+{
+ mSortColumns.clear();
+}
+
void LLScrollListCtrl::clearColumns()
{
column_map_t::iterator itor;
@@ -2982,7 +3040,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..38450b6313 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -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
@@ -342,8 +343,8 @@ public:
static void onClickColumn(void *userdata);
virtual void updateColumns();
- void calcColumnWidths();
- S32 getMaxContentWidth() { return mMaxContentWidth; }
+ 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
@@ -438,16 +440,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 +459,6 @@ private:
S32 mMaxItemCount;
LLRect mItemListRect;
- S32 mMaxContentWidth;
S32 mColumnPadding;
BOOL mBackgroundVisible;
@@ -496,7 +498,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/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
new file mode 100644
index 0000000000..a189375fbe
--- /dev/null
+++ b/indra/llui/llspellcheck.cpp
@@ -0,0 +1,505 @@
+/**
+ * @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()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) || (0 == sDictMap.size()) )
+ {
+ llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
+ if ( (!app_file.is_open()) || (0 == 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 100644
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 100644
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/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 7aeeae298f..3815eec447 100644
--- 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"
@@ -155,6 +156,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),
@@ -181,6 +183,9 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
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 ),
@@ -246,6 +251,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
addChild(mDocumentView);
}
+ if (mSpellCheck)
+ {
+ LLSpellChecker::setSettingsChangeCallback(boost::bind(&LLTextBase::onSpellCheckSettingsChange, this));
+ }
+ mSpellCheckTimer.reset();
+
createDefaultSegment();
updateRects();
@@ -280,12 +291,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.
@@ -530,8 +552,92 @@ 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;
+ while ( (word_start < wstrText.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;
+ }
+
+ // Don't process words shorter than 3 characters
+ std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
+ 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;
+ }
+ }
+
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 +672,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 +685,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 +739,7 @@ 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
+ S32 old_len = getLength(); // length() returns character length
S32 insert_len = wstr.length();
pos = getEditableIndex(pos, true);
@@ -653,8 +799,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 +814,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
- LLWString text(getWText());
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
{
@@ -715,8 +859,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();
@@ -733,9 +876,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
{
return 0;
}
- LLWString text(getWText());
- text[pos] = wc;
- getViewModel()->setDisplay(text);
+ getViewModel()->getEditableDisplay()[pos] = wc;
onValueChange(pos, pos + 1);
needsReflow(pos);
@@ -1103,6 +1244,99 @@ 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;
+}
// Sets the scrollbar from the cursor position
void LLTextBase::updateScrollFromCursor()
@@ -1685,6 +1919,8 @@ 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);
@@ -1693,15 +1929,13 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para
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 +1971,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 +1996,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;
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 0549141b72..90b147cee1 100644
--- 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"
@@ -230,7 +231,8 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
///
class LLTextBase
: public LLUICtrl,
- protected LLEditMenuHandler
+ protected LLEditMenuHandler,
+ public LLSpellCheckMenuHandler
{
public:
friend class LLTextSegment;
@@ -259,6 +261,7 @@ public:
border_visible,
track_end,
read_only,
+ spellcheck,
allow_scroll,
plain_text,
wrap,
@@ -311,6 +314,24 @@ public:
/*virtual*/ BOOL canDeselect() const;
/*virtual*/ void deselect();
+ // 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; }
@@ -540,6 +561,14 @@ protected:
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
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 6a905b7ec0..11cfa1d263 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -150,7 +150,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/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 9720dded6c..1e3a99c088 100644
--- 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
///////////////////////////////////////////////////////////////////
@@ -1093,7 +1095,8 @@ void LLTextEditor::addChar(llwchar wc)
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
}
-void LLTextEditor::addLineBreakChar()
+
+void LLTextEditor::addLineBreakChar(BOOL group_together)
{
if( !getEnabled() )
{
@@ -1111,7 +1114,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);
}
@@ -1434,21 +1437,28 @@ void LLTextEditor::pasteHelper(bool is_primary)
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()));
+ 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.
+ }
deselect();
@@ -1953,7 +1963,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);
}
@@ -2838,6 +2879,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..7d2dd09a28 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -239,7 +239,7 @@ 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);
diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp
index d29260750f..e4d1a37569 100644
--- 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;
}
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 58fa8a0828..80d079cbc8 100644
--- 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/llui.cpp b/indra/llui/llui.cpp
index b5e27616b7..6d2bc1837c 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -831,7 +831,11 @@ void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LL
gGL.flush();
glLineWidth(2.5f);
- glLineStipple(2, 0x3333 << shift);
+
+ if (!LLGLSLShader::sNoFixedFunction)
+ {
+ glLineStipple(2, 0x3333 << shift);
+ }
gGL.begin(LLRender::LINES);
{
@@ -1832,88 +1836,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()
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 28e84fa444..c5a12d2b31 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -292,11 +292,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; }
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 9455d09cc0..ffeff15968 100644
--- 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/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 25e7a31e90..bd06476936 100644
--- 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)
{
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index d612ad5005..f6971261d7 100644
--- 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;
@@ -169,32 +162,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 +204,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
@@ -308,9 +290,6 @@ private:
// 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/llview.cpp b/indra/llui/llview.cpp
index 54843227b7..ad9bec9f61 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1549,16 +1549,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/llviewmodel.h b/indra/llui/llviewmodel.h
index 763af5d8a2..ef2e314799 100644
--- 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/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index cb3b7abb14..74ed72ef97 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -40,9 +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;
+ callback_connection_t connection;
+ return connection;
}
bool LLAvatarNameCache::useDisplayNames()
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index a819d12861..3c68b279f7 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -36,6 +36,8 @@ 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)
@@ -73,8 +75,8 @@ target_link_libraries(llvfs
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 32d081d552..5e5aeefba1 100644
--- 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,8 @@ LLDir::LLDir()
mOSCacheDir(""),
mCAFile(""),
mTempDir(""),
- mDirDelimiter("/") // fallback to forward slash if not overridden
+ mDirDelimiter("/"), // fallback to forward slash if not overridden
+ mLanguage("en")
{
}
@@ -96,9 +116,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
LLDirIterator iter(dirname, mask);
while (iter.next(filename))
{
- fullpath = dirname;
- fullpath += getDirDelimiter();
- fullpath += filename;
+ fullpath = add(dirname, filename);
if(LLFile::isdir(fullpath))
{
@@ -270,12 +288,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;
}
@@ -298,19 +316,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
@@ -323,6 +346,39 @@ const std::string &LLDir::getLLPluginDir() const
return mLLPluginDir;
}
+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);
@@ -343,15 +399,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:
@@ -363,16 +415,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;
@@ -386,9 +444,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:
@@ -412,9 +468,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:
@@ -422,56 +476,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;
}
@@ -511,31 +545,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);
+}
+
+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);
+ }
+ }
+ }
- std::string found_file = findFile(filename, search_paths);
- return found_file;
+ 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
@@ -546,12 +756,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
@@ -587,9 +792,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
{
@@ -621,9 +824,7 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
std::string userlower(username);
LLStringUtil::toLower(userlower);
LLStringUtil::replaceChar(userlower, ' ', '_');
- mPerAccountChatLogsDir = getChatLogsDir();
- mPerAccountChatLogsDir += mDirDelimiter;
- mPerAccountChatLogsDir += userlower;
+ mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
}
else
{
@@ -632,25 +833,59 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
}
-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)
@@ -664,7 +899,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)
{
@@ -697,6 +932,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..300ff1eef6 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file lldir.h
* @brief Definition of directory utilities class
*
@@ -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,9 +98,10 @@ 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
@@ -117,10 +116,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 +182,37 @@ 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 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,10 +230,18 @@ 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
};
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index 407f3b93fb..4edd078640 100644
--- 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
--- 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..c5041d434c 100644
--- 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;
+ //SPATTERS 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
--- 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
--- 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
--- 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..462d1cce06 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -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
--- 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/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp
index ff92cbb7fd..460d2a8b4f 100644
--- 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/llvfs_objc.h b/indra/llvfs/llvfs_objc.h
new file mode 100644
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 100644
index 0000000000..4f9e2f81e9
--- /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];
+ //SPATTERS 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/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp
index ea321c5ae9..3cff622a4b 100644
--- 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/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index 53cecf9d4a..8b356ba138 100644
--- 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..c155c1b362 100644
--- 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();
@@ -107,8 +99,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 +125,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/llkeyboardmacosx.cpp b/indra/llwindow/llkeyboardmacosx.cpp
index ecc2631669..7f8f303517 100644
--- a/indra/llwindow/llkeyboardmacosx.cpp
+++ b/indra/llwindow/llkeyboardmacosx.cpp
@@ -299,28 +299,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/llkeyboardsdl.cpp b/indra/llwindow/llkeyboardsdl.cpp
index 4bb9603368..7c9aa1d340 100644
--- 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/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp
index df78816bd6..be3fe5deb0 100644
--- 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/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 32bb84cba5..97637c937f 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -2809,42 +2809,48 @@ 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;
@@ -2950,6 +2956,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;
@@ -2994,6 +3006,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);
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 52ba8b3bf3..af83b50097 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -36,8 +36,8 @@
#include <AGL/agl.h>
// AssertMacros.h does bad things.
+#include "fix_macros.h"
#undef verify
-#undef check
#undef require
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 3d33af9d9b..39f8a36a6e 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -2117,6 +2117,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;
@@ -2640,8 +2646,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
--- 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 e07fbddb94..9a4dd41c4e 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -367,6 +367,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;
@@ -1698,6 +1702,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"));
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 0809d95628..53d9380f4f 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -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,12 +250,13 @@ 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);
}
}
@@ -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,7 +288,7 @@ void LLControlVariable::resetToDefault(bool fire_signal)
if(fire_signal)
{
- firePropertyChanged();
+ firePropertyChanged(originalValue);
}
}
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 597031ec70..9a3a40e476 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -98,7 +98,7 @@ 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;
private:
std::string mName;
@@ -146,11 +146,11 @@ public:
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);
};
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 2ffb0d8503..b775249219 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -897,7 +897,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)
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index 420e836e36..3906a3bb8c 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -23,12 +23,14 @@ include_directories(
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 +57,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 100644
index 0000000000..a30d8d205c
--- /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 100644
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
--- 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
--- 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
--- 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 100644
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 100644
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
--- 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/mac_updater.h b/indra/mac_updater/mac_updater.h
new file mode 100644
index 0000000000..f65b481cb6
--- /dev/null
+++ b/indra/mac_updater/mac_updater.h
@@ -0,0 +1,91 @@
+/**
+ * @file mac_updater.h
+ * @brief
+ *
+ * $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 <iostream>
+#include <pthread.h>
+#include <boost/filesystem.hpp>
+
+#ifndef LL_MAC_UPDATER_H
+#define LL_MAC_UPDATER_H
+extern bool gCancelled;
+extern bool gFailure;
+
+void *updatethreadproc(void*);
+std::string* walkParents( signed int depth, std::string* childpath );
+std::string* getUserTrashFolder();
+
+void setProgress(int cur, int max);
+void setProgressText(const std::string& str);
+void sendProgress(int cur, int max, std::string str);
+void sendDone();
+void sendStopAlert();
+
+bool isFSRefViewerBundle(const std::string& targetURL);
+bool isDirWritable(const std::string& dir_name);
+bool mkTempDir(boost::filesystem::path& temp_dir);
+bool copyDir(const std::string& src_dir, const std::string& dest_dir);
+
+int oldmain();
+
+class LLMacUpdater
+{
+public:
+ LLMacUpdater();
+ void doUpdate();
+ const std::string walkParents( signed int depth, const std::string& childpath );
+ bool isApplication(const std::string& app_str);
+ void filterFile(const char* filename);
+
+ bool findAppBundleOnDiskImage(const boost::filesystem::path& dir_path,
+ boost::filesystem::path& path_found);
+
+ bool verifyDirectory(const boost::filesystem::path* directory, bool isParent=false);
+ bool getViewerDir(boost::filesystem::path &app_dir);
+ bool downloadDMG(const std::string& dmgName, boost::filesystem::path* temp_dir);
+ bool doMount(const std::string& dmgName, char* deviceNode, const boost::filesystem::path& temp_dir);
+ bool moveApplication (const boost::filesystem::path& app_dir,
+ const boost::filesystem::path& temp_dir,
+ boost::filesystem::path& aside_dir);
+ bool doInstall(const boost::filesystem::path& app_dir,
+ const boost::filesystem::path& temp_dir,
+ boost::filesystem::path& mount_dir,
+ bool replacingTarget);
+ void* updatethreadproc(void*);
+ static void* sUpdatethreadproc(void*);
+
+public:
+ std::string *mUpdateURL;
+ std::string *mProductName;
+ std::string *mBundleID;
+ std::string *mDmgFile;
+ std::string *mMarkerPath;
+ std::string *mApplicationPath;
+ static LLMacUpdater *sInstance;
+
+};
+#endif
+
+
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 0a267cbad0..dff2c04fbc 100644..100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -13,16 +13,18 @@ include(EXPAT)
include(FMOD)
include(OPENAL)
include(FindOpenGL)
+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)
@@ -44,6 +46,11 @@ include(VisualLeakDetector)
include(GLOD)
include(CMakeCopyIfDifferent)
+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)
+
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
${JSONCPP_INCLUDE_DIR}
@@ -51,13 +58,15 @@ include_directories(
${LLAUDIO_INCLUDE_DIRS}
${LLCHARACTER_INCLUDE_DIRS}
${LLCOMMON_INCLUDE_DIRS}
- ${LLCONVEXDECOMP_INCLUDE_DIRS}
+ ${LLCOREHTTP_INCLUDE_DIRS}
+ ${LLPHYSICS_INCLUDE_DIRS}
${FMOD_INCLUDE_DIR}
${LLIMAGE_INCLUDE_DIRS}
${LLKDU_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
+ ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
${LLPLUGIN_INCLUDE_DIRS}
${LLPRIMITIVE_INCLUDE_DIRS}
${LLRENDER_INCLUDE_DIRS}
@@ -70,6 +79,7 @@ include_directories(
${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
)
@@ -89,6 +99,7 @@ set(viewer_SOURCE_FILES
llagentwearables.cpp
llagentwearablesfetch.cpp
llanimstatelabels.cpp
+ llappcorehttp.cpp
llappearancemgr.cpp
llappviewer.cpp
llappviewerlistener.cpp
@@ -96,6 +107,7 @@ set(viewer_SOURCE_FILES
llassetuploadresponders.cpp
llattachmentsmgr.cpp
llaudiosourcevo.cpp
+ llautoreplace.cpp
llavataractions.cpp
llavatariconctrl.cpp
llavatarlist.cpp
@@ -167,6 +179,7 @@ set(viewer_SOURCE_FILES
llfloaterabout.cpp
llfloaterbvhpreview.cpp
llfloaterauction.cpp
+ llfloaterautoreplacesettings.cpp
llfloateravatar.cpp
llfloateravatarpicker.cpp
llfloateravatartextures.cpp
@@ -210,12 +223,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
@@ -232,6 +248,7 @@ set(viewer_SOURCE_FILES
llfloatersidepanelcontainer.cpp
llfloatersnapshot.cpp
llfloatersounddevices.cpp
+ llfloaterspellchecksettings.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
@@ -320,6 +337,7 @@ set(viewer_SOURCE_FILES
llmediactrl.cpp
llmediadataclient.cpp
llmemoryview.cpp
+ llmenuoptionpathfindingrebakenavmesh.cpp
llmeshrepository.cpp
llmimetypes.cpp
llmorphview.cpp
@@ -412,6 +430,17 @@ 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
llphysicsmotion.cpp
llphysicsshapebuilderutil.cpp
llplacesinventorybridge.cpp
@@ -646,6 +675,7 @@ set(viewer_HEADER_FILES
llagentwearables.h
llagentwearablesfetch.h
llanimstatelabels.h
+ llappcorehttp.h
llappearance.h
llappearancemgr.h
llappviewer.h
@@ -654,6 +684,7 @@ set(viewer_HEADER_FILES
llassetuploadresponders.h
llattachmentsmgr.h
llaudiosourcevo.h
+ llautoreplace.h
llavataractions.h
llavatariconctrl.h
llavatarlist.h
@@ -725,6 +756,7 @@ set(viewer_HEADER_FILES
llfloaterabout.h
llfloaterbvhpreview.h
llfloaterauction.h
+ llfloaterautoreplacesettings.h
llfloateravatar.h
llfloateravatarpicker.h
llfloateravatartextures.h
@@ -768,12 +800,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
@@ -790,6 +825,7 @@ set(viewer_HEADER_FILES
llfloatersidepanelcontainer.h
llfloatersnapshot.h
llfloatersounddevices.h
+ llfloaterspellchecksettings.h
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
@@ -878,6 +914,7 @@ set(viewer_HEADER_FILES
llmediactrl.h
llmediadataclient.h
llmemoryview.h
+ llmenuoptionpathfindingrebakenavmesh.h
llmeshrepository.h
llmimetypes.h
llmorphview.h
@@ -959,6 +996,17 @@ 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
llphysicsmotion.h
llphysicsshapebuilderutil.h
llplacesinventorybridge.h
@@ -1308,6 +1356,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
@@ -1516,10 +1569,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(
@@ -1536,7 +1588,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
@@ -1544,7 +1596,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
@@ -1574,6 +1626,9 @@ if (WINDOWS)
${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
@@ -1724,6 +1779,17 @@ if (WINDOWS)
#${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
@@ -1750,8 +1816,10 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLXML_LIBRARIES}
${LSCRIPT_LIBRARIES}
${LLMATH_LIBRARIES}
+ ${LLCOREHTTP_LIBRARIES}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
+ ${HUNSPELL_LIBRARY}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
@@ -1770,7 +1838,8 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${OPENSSL_LIBRARIES}
${CRYPTO_LIBRARIES}
${LLLOGIN_LIBRARIES}
- ${LLCONVEXDECOMP_LIBRARY}
+ ${LLPHYSICS_LIBRARIES}
+ ${LLPHYSICSEXTENSIONS_LIBRARIES}
${TCMALLOC_LIBRARIES}
)
@@ -1892,6 +1961,12 @@ if (DARWIN)
)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater 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})
@@ -1911,6 +1986,7 @@ if (DARWIN)
--login_channel=${VIEWER_LOGIN_CHANNEL}
--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
)
@@ -1922,8 +1998,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")
@@ -1932,13 +2009,20 @@ 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}/mac_updater/${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-updater 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}*")
@@ -1958,7 +2042,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"
@@ -1995,6 +2079,12 @@ if (LL_TESTS)
LL_TEST_ADDITIONAL_LIBRARIES "${JSONCPP_LIBRARIES}"
)
+ 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/app_settings/autoreplace.xml b/indra/newview/app_settings/autoreplace.xml
new file mode 100644
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 be79f91919..7ab7787d77 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -101,7 +101,7 @@
<key>grid</key>
<map>
<key>desc</key>
- <string>Specify the name of the grid, local, or an IP address to connect to.</string>
+ <string>Specify the name of the grid to connect to.</string>
<key>count</key>
<integer>1</integer>
<key>map-to</key>
@@ -117,16 +117,6 @@
<string>h</string>
</map>
- <key>helperuri</key>
- <map>
- <key>desc</key>
- <string>helper web CGI prefix to use</string>
- <key>count</key>
- <integer>1</integer>
- <key>map-to</key>
- <string>CmdLineHelperURI</string>
- </map>
-
<key>ignorepixeldepth</key>
<map>
<key>desc</key>
@@ -163,7 +153,7 @@
<key>map-to</key>
<string>UserLogFile</string>
</map>
-
+
<key>login</key>
<map>
<key>desc</key>
@@ -174,28 +164,6 @@
<string>UserLoginInfo</string>
</map>
- <key>loginpage</key>
- <map>
- <key>desc</key>
- <string>Login authentication page to use.</string>
- <key>count</key>
- <integer>1</integer>
- <key>map-to</key>
- <string>LoginPage</string>
- </map>
-
- <key>loginuri</key>
- <map>
- <key>desc</key>
- <string>login server and CGI script to use</string>
- <key>count</key>
- <integer>1</integer>
- <key>compose</key>
- <boolean>true</boolean>
- <key>map-to</key>
- <string>CmdLineLoginURI</string>
- </map>
-
<key>logmetrics</key>
<map>
<key>desc</key>
@@ -226,7 +194,7 @@
<map>
<key>map-to</key>
<string>NoAudio</string>
- </map>
+ </map>
<key>noinvlib</key>
<map>
@@ -242,7 +210,7 @@
<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>
- </map>
+ </map>
<key>nopreload</key>
<map>
@@ -321,7 +289,7 @@
<key>map-to</key>
<string>QuitAfterSeconds</string>
</map>
-
+
<key>replaysession</key>
<map>
<key>desc</key>
@@ -335,7 +303,7 @@
<key>map-to</key>
<string>RotateRight</string>
</map>
-
+
<key>safe</key>
<map>
<key>desc</key>
@@ -389,7 +357,7 @@
<key>count</key>
<integer>1</integer>
<key>map-to</key>
- <string>SkinFolder</string>
+ <string>SkinCurrent</string>
</map>
<key>slurl</key>
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index 318b69438a..6120f22ba4 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -559,6 +559,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/settings.xml b/indra/newview/app_settings/settings.xml
index c9b4de0140..7deb1284b9 100644..100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -148,7 +148,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>
@@ -335,6 +335,17 @@
<key>Value</key>
<integer>1</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>
@@ -3259,6 +3270,17 @@
<key>Value</key>
<integer>0</integer>
</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>
@@ -4029,17 +4051,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>
@@ -4293,6 +4304,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>
@@ -5001,7 +5023,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>
@@ -5733,7 +5755,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>MemoryPrivatePoolSize</key>
<map>
@@ -6101,7 +6123,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>
@@ -6356,17 +6378,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>
@@ -7274,7 +7285,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>
@@ -8079,7 +8090,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0</real>
+ <real>-0.007</real>
</map>
<key>RenderShadowOffsetError</key>
<map>
@@ -8093,6 +8104,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>
@@ -9172,7 +9195,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>
@@ -9180,7 +9203,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>
@@ -10743,6 +10778,17 @@
<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>
@@ -10754,6 +10800,83 @@
<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>
+ <integer>0.0</integer>
+ </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>
@@ -10863,7 +10986,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>
@@ -12227,6 +12351,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>
@@ -12238,6 +12373,17 @@
<key>Value</key>
<integer>0</integer>
</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>SpeakerParticipantDefaultOrder</key>
<map>
<key>Comment</key>
@@ -12260,6 +12406,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>
@@ -13595,5 +13763,324 @@
<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>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>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
index cb87b754b4..1113a9845b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,6 +31,8 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
+uniform float minimum_alpha;
+
uniform sampler2DRect depthMap;
uniform sampler2D diffuseMap;
@@ -70,9 +72,15 @@ void main()
vec4 diff= texture2D(diffuseMap,vary_texcoord0.xy);
+ if (diff.a < minimum_alpha)
+ {
+ discard;
+ }
+
vec4 col = vec4(vary_ambient + vary_directional.rgb, 1.0);
vec4 color = diff * col;
+
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 46d2aa4877..bfd9b9b3eb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -46,6 +46,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(nvn.xyz * 0.5 + 0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 680eadb852..23c4ea2fff 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -52,5 +52,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(nvn.xyz * 0.5 + 0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index b2027d3a5d..c1fa9e4aac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -49,6 +49,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(nvn.xyz * 0.5 + 0.5, 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..4c68123fac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -48,5 +48,5 @@ void main()
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(nvn.xyz * 0.5 + 0.5, 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..ad65c7d330 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -49,6 +49,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(nvn.xyz * 0.5 + 0.5, 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..86390bdd83 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -42,6 +42,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(nvn.xyz * 0.5 + 0.5, 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..788b966af8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -41,5 +41,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(vary_normal);
- frag_data[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
+ frag_data[2] = vec4(nvn.xyz * 0.5 + 0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
index e02a7b405b..2cef8f2a5d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
@@ -2093,7 +2093,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/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 4d01eeb64e..7e79317543 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -79,7 +79,7 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 75de47614c..bff87cb6aa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -55,8 +55,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;
@@ -143,7 +141,8 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0, norm.z);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 19800a8b8e..75757b26c8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -42,12 +42,13 @@ 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;
@@ -74,7 +75,7 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos;
+ vec3 lv = trans_center.xyz-pos;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
@@ -83,7 +84,7 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
index cb14e6d4e8..9491421236 100644
--- 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*sqrt(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/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
new file mode 100644
index 0000000000..6195e2f1ec
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -0,0 +1,44 @@
+/**
+ * @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;
+
+VARYING vec4 post_pos;
+
+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);
+
+ post_pos = pos;
+
+ gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 66e3cf6d13..89448e2167 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -277,7 +277,7 @@ void main()
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
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 7ed8ed3370..cca63872de 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -24,18 +24,21 @@
*/
-#extension GL_ARB_texture_rectangle : enable
-
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
#define frag_color gl_FragColor
#endif
+//class 1 -- no shadows
+
+#extension GL_ARB_texture_rectangle : enable
+
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
+uniform samplerCube environmentMap;
uniform sampler2D noiseMap;
uniform sampler2D projectionMap;
@@ -46,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;
@@ -53,19 +57,66 @@ 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 vec3 color;
uniform float falloff;
uniform float size;
VARYING vec4 vary_fragcoord;
+VARYING vec3 trans_center;
+
uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ 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);
+
+ 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);
+
+ 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 +135,16 @@ void main()
frag.xy *= screen_res;
vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
+ vec3 lv = trans_center.xyz-pos.xyz;
float dist2 = dot(lv,lv);
dist2 /= size;
if (dist2 > 1.0)
{
discard;
}
-
+
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = vec3((norm.xy-0.5)*2.0, norm.z);
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -107,7 +158,11 @@ 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-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -125,32 +180,32 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
+ float amb_da = proj_ambiance;
+
if (da > 0.0)
{
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 = color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
+ amb_da += (da*0.5)*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;
}
@@ -168,18 +223,22 @@ 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(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 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb;
}
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
index 2422d73a3e..bac74cbbef 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -123,7 +123,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 = (norm.xyz-0.5)*2.0; // unpack norm
frag_color[0] = 1.0;
frag_color[1] = calcAmbientOcclusion(pos, norm);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 8a5e482e80..daf1cc7ea2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -56,6 +56,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(nvn.xyz * 0.5 + 0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 6cf6106b51..da253846ef 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -48,5 +48,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(nvn.xyz * 0.5 + 0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index 42dc7c0980..3427d6db57 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -161,5 +161,5 @@ void main()
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[2] = vec4(screenspacewavef.xyz*0.5+0.5, screenspacewavef.z*0.5); // normalxyz, displace
}
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 100644
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 100644
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/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
new file mode 100644
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/pathfindingF.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
new file mode 100644
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 100644
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 100644
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/objects/indexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
index 7c0699d72f..ca29bf3143 100644
--- 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/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
new file mode 100644
index 0000000000..44f1aa34a0
--- /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 vec3 binormal;
+
+VARYING vec4 binormal_out;
+
+void main()
+{
+ binormal_out = vec4(normal_matrix * binormal, 0.0);
+}
+
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 100644
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 100644
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 100644
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 100644
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/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 8db4cb58cf..12706f130b 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -34,10 +34,10 @@ out vec4 frag_color;
VARYING vec4 vertex_color;
VARYING vec2 vary_texcoord0;
-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 sampler2DRect depthMap;
uniform mat4 shadow_matrix[6];
@@ -58,22 +58,22 @@ uniform float shadow_bias;
uniform mat4 inv_proj;
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
-
- stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+
+ 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 = shadow2DRect(shadowMap, stc.xyz).x;
+ float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
-
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 0.0)).x;
-
- return shadow*0.2;
+
+ 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;
}
@@ -99,8 +99,7 @@ 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)*w;
@@ -111,8 +110,7 @@ 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;
@@ -123,8 +121,7 @@ void main()
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;
@@ -135,8 +132,7 @@ void main()
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;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
index 33958a5010..228dc104ac 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedF.glsl
@@ -31,17 +31,16 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-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 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);
@@ -54,6 +53,7 @@ VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
VARYING vec4 vertex_color;
+uniform vec2 shadow_res;
uniform float shadow_bias;
uniform mat4 inv_proj;
@@ -71,22 +71,22 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
- stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.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 = shadow2DRect(shadowMap, stc.xyz).x;
+ float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
-
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 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;
+ 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;
+ return shadow*0.2;
}
@@ -112,8 +112,7 @@ 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)*w;
@@ -124,8 +123,7 @@ 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;
@@ -136,8 +134,7 @@ void main()
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;
@@ -148,8 +145,7 @@ void main()
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;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
index ba6f3ace53..c3950a10e1 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaNonIndexedNoColorF.glsl
@@ -31,17 +31,18 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
+uniform float minimum_alpha;
+
+uniform sampler2DShadow shadowMap0;
+uniform sampler2DShadow shadowMap1;
+uniform sampler2DShadow shadowMap2;
+uniform sampler2DShadow 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);
@@ -53,6 +54,8 @@ VARYING vec3 vary_position;
VARYING vec3 vary_pointlight_col;
VARYING vec2 vary_texcoord0;
+uniform vec2 shadow_res;
+
uniform float shadow_bias;
uniform mat4 inv_proj;
@@ -70,20 +73,20 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc)
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc)
{
stc.xyz /= stc.w;
stc.z += shadow_bias;
- stc.x = floor(stc.x + fract(stc.y*12345)); // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
+ stc.x = floor(stc.x*shadow_res.x + fract(stc.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 cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 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;
+ 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;
}
@@ -97,6 +100,13 @@ void main()
float shadow = 0.0;
vec4 pos = vec4(vary_position, 1.0);
+ vec4 diff = texture2D(diffuseMap,vary_texcoord0.xy);
+
+ if (diff.a < minimum_alpha)
+ {
+ discard;
+ }
+
vec4 spos = pos;
if (spos.z > -shadow_clip.w)
@@ -111,8 +121,7 @@ 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)*w;
@@ -123,8 +132,7 @@ 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;
@@ -135,8 +143,7 @@ void main()
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;
@@ -147,8 +154,7 @@ void main()
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;
@@ -164,8 +170,6 @@ void main()
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;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index f7f1f649ce..5621e47ab7 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -154,7 +154,7 @@ void main()
}
vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index a137bea30f..9df9d75905 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -279,7 +279,7 @@ void main()
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
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 99a277fbfc..6d6ad6d565 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -31,8 +31,6 @@ out vec4 frag_color;
#define frag_color gl_FragColor
#endif
-VARYING vec4 vertex_color;
-
uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect depthMap;
@@ -49,6 +47,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 +57,65 @@ 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;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ 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);
+
+ 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);
+
+ 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 +133,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 dist2 = dot(lv,lv);
+ dist2 /= size;
+ if (dist2 > 1.0)
+ {
+ discard;
+ }
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
@@ -96,17 +153,8 @@ 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
+ norm = (norm.xyz-0.5)*2.0; // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -119,8 +167,12 @@ 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-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -138,37 +190,33 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
+ float amb_da = proj_ambiance;
+
if (da > 0.0)
{
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;
+ vec3 lcol = 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)
- {
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;
}
@@ -185,19 +233,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(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 &&
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;
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ col += dist_atten*scol.rgb*color.rgb*scol.a*spec.rgb*shadow;
}
}
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index db3d760359..890486c4b1 100644
--- 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,10 +55,10 @@ 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;
@@ -78,30 +78,31 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
+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 + fract(pos_screen.y*0.666666666)); // add some jitter to X sample pos according to Y to disguise the snapping going on here
+ 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 cs = shadow2DRect(shadowMap, stc.xyz).x;
float shadow = cs;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, -1.5, 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;
+ 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*0.2;
+ return shadow*0.2;
}
-float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
+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;
@@ -125,7 +126,7 @@ 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
+ nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
float displace = nmap4.w;
vec3 norm = nmap4.xyz;
@@ -162,8 +163,7 @@ 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, pos_screen)*w;
@@ -174,8 +174,7 @@ 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;
@@ -186,7 +185,6 @@ void main()
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;
@@ -198,7 +196,6 @@ void main()
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;
@@ -237,11 +234,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
+ 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, pos_screen);
+ 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 dfe108eb01..2dcd3d656f 100644
--- 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,10 +55,11 @@ 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;
@@ -139,30 +140,30 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm)
return min(ret, 1.0);
}
-float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl, vec2 pos_screen)
+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 + fract(pos_screen.y*0.666666666));
+ 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 += shadow2DRect(shadowMap, stc.xyz+vec3(2.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(1.0, -1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-1.0, 1.5, 0.0)).x;
- shadow += shadow2DRect(shadowMap, stc.xyz+vec3(-2.0, -1.5, 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;
+ 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, vec2 pos_screen)
+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;
@@ -186,7 +187,7 @@ 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
+ nmap4 = vec4((nmap4.xyz-0.5)*2.0,nmap4.w); // unpack norm
float displace = nmap4.w;
vec3 norm = nmap4.xyz;
@@ -223,8 +224,7 @@ 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, pos_screen)*w;
@@ -235,8 +235,7 @@ 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;
@@ -247,8 +246,7 @@ void main()
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;
@@ -259,8 +257,7 @@ void main()
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;
@@ -298,11 +295,11 @@ void main()
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- frag_color[2] = pcfShadow(shadowMap4, lpos, 0.8, pos_screen);
+ 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, pos_screen);
+ frag_color[3] = pcfSpotShadow(shadowMap5, lpos, 0.8, pos_screen);
//frag_color.rgb = pos.xyz;
//frag_color.b = shadow;
diff --git a/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING.tif
new file mode 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..5166af6e05
--- /dev/null
+++ b/indra/newview/cursors_mac/UI_CURSOR_PATHFINDING_START_ADD.tif
Binary files differ
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e8a109e661..4030324ecb 100644
--- 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
@@ -97,10 +97,10 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
@@ -129,16 +129,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
//
-// Mid Graphics Settings
+// Medium Low Graphics Settings
//
-list Mid
+list LowMid
RenderAnisotropic 1 0
RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
@@ -159,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
@@ -189,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
@@ -230,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)
@@ -244,18 +338,30 @@ 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
@@ -520,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 3a0e7e3697..6d5284c602 100644
--- 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
@@ -94,10 +94,10 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
-WLSkyDetail 1 48
RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderShadowDetail 1 0
+WLSkyDetail 1 48
RenderFSAASamples 1 0
//
@@ -125,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
@@ -143,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
@@ -155,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
@@ -173,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
@@ -185,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
//
@@ -226,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)
@@ -240,18 +333,30 @@ 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
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 96362ff4bb..1c0d45c11b 100644
--- 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
@@ -96,10 +96,10 @@ 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
//
@@ -127,16 +127,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 1
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
@@ -145,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
@@ -157,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
@@ -175,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
@@ -187,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!)
//
@@ -242,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
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index 398a64378e..68e09d010e 100644
--- 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
@@ -63,9 +63,9 @@ 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
@@ -96,10 +96,10 @@ 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
//
@@ -127,16 +127,16 @@ RenderUseImpostors 1 1
RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 1
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
@@ -145,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
@@ -157,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
@@ -175,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
@@ -187,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
//
@@ -242,18 +332,30 @@ 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
@@ -517,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/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 5ebec1563e..4181e4ebb3 100644
--- 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 777d54a5c3..4c39014c8b 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -17,520 +17,582 @@
//
// 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 R300 (9700) .*R300.* 1 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 0
+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 ASUS ARES .*ATI.*ASUS.*ARES.* 3 1 0 0
+ATI ASUS A9xxx .*ATI.*ASUS.*A9.* 1 1 0 0
+ATI ASUS AH24xx .*ATI.*ASUS.*AH24.* 1 1 1 3.3
+ATI ASUS AH26xx .*ATI.*ASUS.*AH26.* 1 1 1 3.3
+ATI ASUS AH34xx .*ATI.*ASUS.*AH34.* 1 1 1 3.3
+ATI ASUS AH36xx .*ATI.*ASUS.*AH36.* 1 1 1 3.3
+ATI ASUS AH46xx .*ATI.*ASUS.*AH46.* 2 1 1 3.3
+ATI ASUS AX3xx .*ATI.*ASUS.*AX3.* 1 1 0 0
+ATI ASUS AX5xx .*ATI.*ASUS.*AX5.* 1 1 0 0
+ATI ASUS AX8xx .*ATI.*ASUS.*AX8.* 2 1 0 0
+ATI ASUS EAH24xx .*ATI.*ASUS.*EAH24.* 2 1 0 0
+ATI ASUS EAH26xx .*ATI.*ASUS.*EAH26.* 3 1 0 0
+ATI ASUS EAH29xx .*ATI.*ASUS.*EAH29.* 3 1 0 0
+ATI ASUS EAH34xx .*ATI.*ASUS.*EAH34.* 1 1 0 0
+ATI ASUS EAH36xx .*ATI.*ASUS.*EAH36.* 2 1 0 0
+ATI ASUS EAH38xx .*ATI.*ASUS.*EAH38.* 2 1 1 3.3
+ATI ASUS EAH43xx .*ATI.*ASUS.*EAH43.* 2 1 1 3.3
+ATI ASUS EAH45xx .*ATI.*ASUS.*EAH45.* 2 1 0 0
+ATI ASUS EAH48xx .*ATI.*ASUS.*EAH48.* 3 1 1 3.3
+ATI ASUS EAH57xx .*ATI.*ASUS.*EAH57.* 3 1 1 4.1
+ATI ASUS EAH58xx .*ATI.*ASUS.*EAH58.* 5 1 1 4.1
+ATI ASUS EAH62xx .*ATI.*ASUS.*EAH62.* 2 1 0 0
+ATI ASUS EAH63xx .*ATI.*ASUS.*EAH63.* 2 1 0 0
+ATI ASUS EAH64xx .*ATI.*ASUS.*EAH64.* 2 1 0 0
+ATI ASUS EAH65xx .*ATI.*ASUS.*EAH65.* 2 1 0 4.1
+ATI ASUS EAH66xx .*ATI.*ASUS.*EAH66.* 3 1 0 4.1
+ATI ASUS EAH67xx .*ATI.*ASUS.*EAH67.* 3 1 0 0
+ATI ASUS EAH68xx .*ATI.*ASUS.*EAH68.* 5 1 0 4
+ATI ASUS EAH69xx .*ATI.*ASUS.*EAH69.* 5 1 0 4.1
+ATI ASUS Radeon X1xxx .*ATI.*ASUS.*X1.* 2 1 1 2.1
+ATI Radeon X7xx .*ATI.*ASUS.*X7.* 1 1 0 0
+ATI Radeon X19xx .*ATI.*(Radeon|Diamond) X19.* ?.* 2 1 1 2.1
+ATI Radeon X18xx .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1
+ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1
+ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X16.* ?.* 1 1 1 2.1
+ATI Radeon X15xx .*ATI.*(Radeon|Diamond) X15.* ?.* 1 1 1 2.1
+ATI Radeon X13xx .*ATI.*(Radeon|Diamond) X13.* ?.* 1 1 1 2.1
+ATI Radeon X1xxx .*ATI.*(Radeon|Diamond) X1.. ?.* 0 1 1 2.1
+ATI Radeon X2xxx .*ATI.*(Radeon|Diamond) X2.. ?.* 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 0
+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 1.3
+ATI Generic .*ATI.*Generic.* 0 0 0 0
+ATI Hercules 9800 .*ATI.*Hercules.*9800.* 1 1 0 0
+ATI IGP 340M .*ATI.*IGP.*340M.* 0 0 0 0
+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 64xx .*ATI.*AMD Radeon.* HD [67]4..[MG] 2 1 1 4.2
+ATI Radeon HD 65xx .*ATI.*AMD Radeon.* HD [67]5..[MG] 2 1 1 4.2
+ATI Radeon HD 66xx .*ATI.*AMD Radeon.* HD [67]6..[MG] 3 1 1 4.2
+ATI Radeon HD 7100 .*ATI.*AMD Radeon.* HD 71.* 2 1 0 0
+ATI Radeon HD 7200 .*ATI.*AMD Radeon.* HD 72.* 2 1 0 0
+ATI Radeon HD 7300 .*ATI.*AMD Radeon.* HD 73.* 2 1 0 4.2
+ATI Radeon HD 7400 .*ATI.*AMD Radeon.* HD 74.* 2 1 0 4.2
+ATI Radeon HD 7500 .*ATI.*AMD Radeon.* HD 75.* 3 1 1 4.2
+ATI Radeon HD 7600 .*ATI.*AMD Radeon.* HD 76.* 3 1 0 4.2
+ATI Radeon HD 7700 .*ATI.*AMD Radeon.* HD 77.* 4 1 1 4.2
+ATI Radeon HD 7800 .*ATI.*AMD Radeon.* HD 78.* 5 1 1 4.2
+ATI Radeon HD 7900 .*ATI.*AMD Radeon.* HD 79.* 5 1 1 4.2
+ATI ASUS HD7100 .*ATI.*ASUS.* HD71.* 2 1 0 0
+ATI ASUS HD7200 .*ATI.*ASUS.* HD72.* 2 1 0 0
+ATI ASUS HD7300 .*ATI.*ASUS.* HD73.* 2 1 0 0
+ATI ASUS HD7400 .*ATI.*ASUS.* HD74.* 2 1 0 0
+ATI ASUS HD7500 .*ATI.*ASUS.* HD75.* 3 1 1 4.2
+ATI ASUS HD7600 .*ATI.*ASUS.* HD76.* 3 1 0 0
+ATI ASUS HD7700 .*ATI.*ASUS.* HD77.* 4 1 1 4.2
+ATI ASUS HD7800 .*ATI.*ASUS.* HD78.* 5 1 1 4.2
+ATI ASUS HD7900 .*ATI.*ASUS.* HD79.* 5 1 1 4.2
+ATI Mobility Radeon 4100 .*ATI.*Mobility.*41.. 1 1 1 3.3
+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 3.3
+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 *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 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 0
+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 Radeon HD 2300 .*ATI.*Radeon HD *23.. 0 1 1 3.3
+ATI Radeon HD 2400 .*ATI.*Radeon HD *24.. 1 1 1 4
+ATI Radeon HD 2600 .*ATI.*Radeon HD *26.. 2 1 1 3.3
+ATI Radeon HD 2900 .*ATI.*Radeon HD *29.. 3 1 1 3.3
+ATI Radeon HD 3000 .*ATI.*Radeon HD *30.. 0 1 0 0
+ATI Radeon HD 3100 .*ATI.*Radeon HD *31.. 1 1 0 0
+ATI Radeon HD 3200 .*ATI.*Radeon HD *32.. 1 1 1 4
+ATI Radeon HD 3300 .*ATI.*Radeon HD *33.. 1 1 1 3.3
+ATI Radeon HD 3400 .*ATI.*Radeon HD *34.. 1 1 1 4
+ATI Radeon HD 3500 .*ATI.*Radeon HD *35.. 2 1 0 0
+ATI Radeon HD 3600 .*ATI.*Radeon HD *36.. 3 1 1 3.3
+ATI Radeon HD 3700 .*ATI.*Radeon HD *37.. 3 1 0 0
+ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3
+ATI Radeon HD 3800 .*ATI.*Radeon HD *38.. 3 1 1 4
+ATI Radeon HD 4100 .*ATI.*Radeon HD *41.. 1 1 0 0
+ATI Radeon HD 4200 .*ATI.*Radeon HD *42.. 1 1 1 4
+ATI Radeon HD 4300 .*ATI.*Radeon HD *43.. 2 1 1 4
+ATI Radeon HD 4400 .*ATI.*Radeon HD *44.. 2 1 0 0
+ATI Radeon HD 4500 .*ATI.*Radeon HD *45.. 2 1 1 3.3
+ATI Radeon HD 4600 .*ATI.*Radeon HD *46.. 3 1 1 4
+ATI Radeon HD 4700 .*ATI.*Radeon HD *47.. 3 1 1 3.3
+ATI Radeon HD 4800 .*ATI.*Radeon HD *48.. 3 1 1 4
+ATI ASUS EAH5400 .*ATI.*ASUS EAH54.. 3 1 1 4.2
+ATI Radeon HD 5400 .*ATI.*Radeon HD *54.. 3 1 1 4.2
+ATI Radeon HD 5500 .*ATI.*Radeon HD *55.. 3 1 1 4.2
+ATI ASUS EAH5500 .*ATI.*ASUS EAH55.. 3 1 1 4.2
+ATI Radeon HD 5600 .*ATI.*Radeon HD *56.. 3 1 1 4.2
+ATI Radeon HD 5700 .*ATI.*Radeon HD *57.. 3 1 1 4.2
+ATI Radeon HD 5800 .*ATI.*Radeon HD *58.. 4 1 1 4.2
+ATI Radeon HD 5900 .*ATI.*Radeon HD *59.. 4 1 1 4.2
+ATI Radeon HD 6200 .*ATI.*Radeon HD *62.. 0 1 1 4.2
+ATI Radeon HD 6300 .*ATI.*Radeon HD *63.. 1 1 1 4.2
+ATI Radeon HD 6400 .*ATI.*Radeon HD *64.. 3 1 1 4.2
+ATI Radeon HD 6500 .*ATI.*Radeon HD *65.. 3 1 1 4.2
+ATI Radeon HD 6600 .*ATI.*Radeon HD *66.. 3 1 1 4.2
+ATI Radeon HD 6700 .*ATI.*Radeon HD *67.. 3 1 1 4.2
+ATI Radeon HD 6800 .*ATI.*Radeon HD *68.. 4 1 1 4.2
+ATI Radeon HD 6900 .*ATI.*Radeon HD *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 ?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 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
+AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.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 0
+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 0
+AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 0
+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 0
+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 0
+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.1
+ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0
+ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 0
+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
+ATI Radeon .*ATI.*(Diamond|Radeon).* 0 1 0 4.2
+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 HD2000 .*Intel.*HD2000.* 2 1 0 0
+Intel HD3000 .*Intel.*HD3000.* 3 1 0 0
+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 2.1
+Gallium .*Gallium.* 1 1 1 2.1
+NVIDIA G100M .*NVIDIA .*100M.* 4 1 1 3.3
+NVIDIA G102M .*NVIDIA .*102M.* 1 1 1 3.3
+NVIDIA G103M .*NVIDIA .*103M.* 2 1 1 3.3
+NVIDIA G105M .*NVIDIA .*105M.* 2 1 1 3.3
+NVIDIA G 110M .*NVIDIA .*110M.* 1 1 1 3.3
+NVIDIA G 120M .*NVIDIA .*120M.* 1 1 1 3.3
+NVIDIA G 205M .*NVIDIA .*205M.* 1 1 0 0
+NVIDIA G 410M .*NVIDIA .*410M.* 3 1 1 4.2
+NVIDIA GT 120M .*NVIDIA .*GT *12*M.* 3 1 1 3.3
+NVIDIA GT 130M .*NVIDIA .*GT *13*M.* 3 1 1 3.3
+NVIDIA GT 140M .*NVIDIA .*GT *14*M.* 3 1 1 3.3
+NVIDIA GT 150M .*NVIDIA .*GTS *15*M.* 2 1 0 0
+NVIDIA GTS 160M .*NVIDIA .*GTS *16*M.* 2 1 0 0
+NVIDIA G210M .*NVIDIA .*G21*M.* 3 1 0 0
+NVIDIA GT 220M .*NVIDIA .*GT *22*M.* 3 1 1 3.3
+NVIDIA GT 230M .*NVIDIA .*GT *23*M.* 3 1 1 3.3
+NVIDIA GT 240M .*NVIDIA .*GT *24*M.* 3 1 1 3.3
+NVIDIA GTS 250M .*NVIDIA .*GTS *25*M.* 3 1 0 0
+NVIDIA GTS 260M .*NVIDIA .*GTS *26*M.* 3 1 0 0
+NVIDIA GTX 260M .*NVIDIA .*GTX *26*M.* 3 1 0 0
+NVIDIA GTX 270M .*NVIDIA .*GTX *27*M.* 3 1 0 0
+NVIDIA GTX 280M .*NVIDIA .*GTX *28*M.* 3 1 0 0
+NVIDIA 300M .*NVIDIA .*30*M.* 3 1 1 4.2
+NVIDIA G 310M .*NVIDIA .*31*M.* 2 1 0 0
+NVIDIA GT 320M .*NVIDIA .*GT *32*M.* 3 1 0 0
+NVIDIA GT 325M .*NVIDIA .*GT *32*M.* 3 1 1 3.3
+NVIDIA GT 330M .*NVIDIA .*GT *33*M.* 3 1 1 3.3
+NVIDIA GT 340M .*NVIDIA .*GT *34*M.* 4 1 1 3.3
+NVIDIA GTS 350M .*NVIDIA .*GTS *35*M.* 4 1 1 3.3
+NVIDIA GTS 360M .*NVIDIA .*GTS *360M.* 5 1 1 3.3
+NVIDIA 405M .*NVIDIA .* 40*M.* 2 1 0 4.2
+NVIDIA 410M .*NVIDIA .* 41*M.* 3 1 0 0
+NVIDIA GT 415M .*NVIDIA .*GT *41*M.* 3 1 1 4.2
+NVIDIA GT 420M .*NVIDIA .*GT *42*M.* 3 1 1 4.2
+NVIDIA GT 430M .*NVIDIA .*GT *43*M.* 3 1 1 4.2
+NVIDIA GT 440M .*NVIDIA .*GT *44*M.* 3 1 1 4.2
+NVIDIA GT 450M .*NVIDIA .*GT *45*M.* 3 1 0 0
+NVIDIA GTX 460M .*NVIDIA .*GTX *46*M.* 4 1 1 4.2
+NVIDIA GTX 470M .*NVIDIA .*GTX *47*M.* 3 1 0 0
+NVIDIA GTX 480M .*NVIDIA .*GTX *48*M.* 3 1 1 4.2
+NVIDIA GT 520M .*NVIDIA .*GT *52*M.* 3 1 1 4.2
+NVIDIA GT 530M .*NVIDIA .*GT *53*M.* 3 1 1 4.2
+NVIDIA GT 540M .*NVIDIA .*GT *54*M.* 3 1 1 4.2
+NVIDIA GT 550M .*NVIDIA .*GT *55*M.* 3 1 1 4.2
+NVIDIA GTX 560M .*NVIDIA .*GTX *56*M.* 3 1 0 0
+NVIDIA GTX 570M .*NVIDIA .*GTX *57*M.* 5 1 0 0
+NVIDIA GTX 580M .*NVIDIA .*GTX *58*M.* 5 1 1 4.2
+NVIDIA 610M .*NVIDIA.* 61*M.* 3 1 1 4.2
+NVIDIA GT 620M .*NVIDIA .*GT *62*M.* 3 1 0 0
+NVIDIA GT 630M .*NVIDIA .*GT *63*M.* 3 1 0 0
+NVIDIA GT 640M .*NVIDIA .*GT *64*M.* 3 1 0 0
+NVIDIA GT 650M .*NVIDIA .*GT *65*M.* 3 1 0 0
+NVIDIA GTX 660M .*NVIDIA .*GTX *66*M.* 5 1 0 0
+NVIDIA GTX 670M .*NVIDIA .*GTX *67*M.* 5 1 1 4.2
+NVIDIA GTX 680M .*NVIDIA .*GTX *68*M.* 5 1 0 0
+NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0
+NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2
+NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 3
+NVIDIA GT 130 .*NVIDIA .*GT *13.* 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 0
+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.2
+NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 4.2
+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 0
+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.2
+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 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.3
+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 3 .*GeForce ?3 ?.* 2 1 1 2.1
+NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0
+NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5
+NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0
+NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0
+NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0
+NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0
+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 0
+NVIDIA GeForce 8200M .*NVIDIA .*GeForce 8200M.* 1 1 0 3.3
+NVIDIA GeForce 8200 .*NVIDIA .*GeForce 82.* 1 1 0 2.1
+NVIDIA GeForce 8300 .*NVIDIA .*GeForce 83.* 3 1 1 3.3
+NVIDIA GeForce 8400M .*NVIDIA .*GeForce 8400M.* 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 8600M.* 2 1 1 3.3
+NVIDIA GeForce 8600 .*NVIDIA .*GeForce 86.* 3 1 1 3.3
+NVIDIA GeForce 8700M .*NVIDIA .*GeForce 8700M.* 2 1 1 3.3
+NVIDIA GeForce 8700 .*NVIDIA .*GeForce 87.* 3 1 0 0
+NVIDIA GeForce 8800M .*NVIDIA .*GeForce 8800M.* 2 1 1 3.3
+NVIDIA GeForce 8800 .*NVIDIA .*GeForce 88.* 3 1 1 3.3
+NVIDIA GeForce 9100M .*NVIDIA .*GeForce 9100M.* 0 1 0 0
+NVIDIA GeForce 9100 .*NVIDIA .*GeForce 91.* 0 1 0 3.3
+NVIDIA GeForce 9200M .*NVIDIA .*GeForce 9200M.* 1 1 0 3.1
+NVIDIA GeForce 9200 .*NVIDIA .*GeForce 92.* 1 1 0 3.3
+NVIDIA GeForce 9300M .*NVIDIA .*GeForce 9300M.* 1 1 1 3.3
+NVIDIA GeForce 9300 .*NVIDIA .*GeForce 93.* 1 1 1 3.3
+NVIDIA GeForce 9400M .*NVIDIA .*GeForce 9400M.* 2 1 1 3.3
+NVIDIA GeForce 9400 .*NVIDIA .*GeForce 94.* 3 1 1 3.3
+NVIDIA GeForce 9500M .*NVIDIA .*GeForce 9500M.* 1 1 1 3.3
+NVIDIA GeForce 9500 .*NVIDIA .*GeForce 95.* 3 1 1 3.3
+NVIDIA GeForce 9600M .*NVIDIA .*GeForce 9600M.* 2 1 1 3.3
+NVIDIA GeForce 9600 .*NVIDIA .*GeForce 96.* 3 1 1 3.3
+NVIDIA GeForce 9700M .*NVIDIA .*GeForce 9700M.* 0 1 1 3.3
+NVIDIA GeForce 9800M .*NVIDIA .*GeForce 9800M.* 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 0
+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 0
+NVIDIA GeForce Go 6400 .*NVIDIA .*GeForce Go 64.* 1 1 1 2
+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 0
+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 0
+NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 0
+NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 3
+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 0
+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 0
+NVIDIA Quadro 1000M .*Quadro.*1000M.* 2 1 0 4.2
+NVIDIA Quadro 2000 M/D .*Quadro.*2000.* 3 1 0 4.2
+NVIDIA Quadro 3000M .*Quadro.*3000M.* 3 1 0 0
+NVIDIA Quadro 4000M .*Quadro.*4000M.* 3 1 0 0
+NVIDIA Quadro 4000 .*Quadro *4000.* 3 1 0 4.2
+NVIDIA Quadro 50x0 M .*Quadro.*50.0.* 3 1 0 0
+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 3.3
+NVIDIA Quadro4 .*Quadro4.* 0 1 0 0
+NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0
+NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0
+NVIDIA Quadro FX 770M .*Quadro.*FX *770M.* 2 1 0 0
+NVIDIA Quadro FX 1500M .*Quadro.*FX *1500M.* 1 1 0 2.1
+NVIDIA Quadro FX 1600M .*Quadro.*FX *1600M.* 2 1 0 0
+NVIDIA Quadro FX 2500M .*Quadro.*FX *2500M.* 2 1 0 0
+NVIDIA Quadro FX 2700M .*Quadro.*FX *2700M.* 3 1 0 0
+NVIDIA Quadro FX 2800M .*Quadro.*FX *2800M.* 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 0
+NVIDIA Quadro FX 3700 .*Quadro.*FX *3700.* 3 1 0 3.3
+NVIDIA Quadro FX 3800 .*Quadro.*FX *3800.* 3 1 0 3.2
+NVIDIA Quadro FX 4500 .*Quadro.*FX *45.* 3 1 0 0
+NVIDIA Quadro FX 880M .*Quadro.*FX *880M.* 3 1 0 3.3
+NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro *FX *4800.* 3 1 0 0
+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 *300M.* 2 1 0 0
+NVIDIA Quadro NVS 320M .*NVIDIA .*NVS *320M.* 2 1 0 0
+NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS *2100M.* 2 1 0 0
+NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS *3100M.* 2 1 0 0
+NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS *4200M.* 2 1 0 4.1
+NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS *5100M.* 2 1 0 0
+NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 3.2
+NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1
+NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 0
+NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 0
+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/llagent.cpp b/indra/newview/llagent.cpp
index 3367604753..b6fd7bc9c2 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -81,6 +81,7 @@
#include "llviewermenu.h"
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
#include "llvoavatarself.h"
@@ -112,6 +113,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 +343,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),
@@ -330,9 +442,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 +466,14 @@ void LLAgent::init()
void LLAgent::cleanup()
{
mRegionp = NULL;
+ if (mTeleportFinishedSlot.connected())
+ {
+ mTeleportFinishedSlot.disconnect();
+ }
+ if (mTeleportFailedSlot.connected())
+ {
+ mTeleportFailedSlot.disconnect();
+ }
}
//-----------------------------------------------------------------------------
@@ -2371,49 +2503,278 @@ 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;
+public:
+ LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
+ virtual ~LLMaturityPreferencesResponder();
+
+ virtual void result(const LLSD &pContent);
+ virtual void error(U32 pStatus, const std::string& pReason);
+
+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)
+ {
+ 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::error(U32 pStatus, const std::string& pReason)
+{
+ llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
+ << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
+ << pReason << "' [status:" << pStatus << "]" << llendl;
+ mAgent->handlePreferredMaturityError();
+}
+
+U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
+{
+ // stinson 05/24/2012 Pathfinding regions have re-defined the response behavior. In the old server code,
+ // if you attempted to change the preferred maturity to the same value, the response content would be an
+ // undefined LLSD block. In the new server code with pathfinding, the response content should always be
+ // defined. Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
+ // into server trunk and fully deployed.
+ U8 maturity = SIM_ACCESS_MIN;
+ if (pContent.isUndefined())
+ {
+ maturity = mPreferredMaturity;
+ }
+ else
+ {
+ llassert(!pContent.isUndefined());
+ llassert(pContent.isMap());
- // Update agent access preference on the server
- std::string url = getRegion()->getCapability("UpdateAgentInformation");
- if (!url.empty())
+ if (!pContent.isUndefined() && pContent.isMap())
+ {
+ // stinson 05/24/2012 Pathfinding regions have re-defined the response syntax. The if statement catches
+ // the new syntax, and the else statement catches the old syntax. After pathfinding is merged into
+ // server trunk and fully deployed, we can remove the else statement.
+ if (pContent.has("access_prefs"))
+ {
+ 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.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);
+ }
+ }
+ else if (pContent.has("max"))
+ {
+ llassert(pContent.get("max").isString());
+ if (pContent.get("max").isString())
+ {
+ LLSD::String actualPreference = pContent.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)
{
- // Set new access preference
- LLSD access_prefs = LLSD::emptyMap();
- if (preferredMaturity == SIM_ACCESS_PG)
+ // 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->error(0U, "region is not defined");
+ }
+ 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->error(0U, "capability 'UpdateAgentInformation' is not defined for region");
+ }
+ 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
@@ -2434,11 +2795,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()
@@ -2451,9 +2813,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()));
}
//----------------------------------------------------------------------------
@@ -3388,7 +3750,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 +3828,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 +3956,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 +3977,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 +4014,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 +4089,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);
@@ -4045,5 +4536,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..99904e118c 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -35,6 +35,8 @@
#include "llcoordframe.h" // for mFrameAgent
#include "llvoavatardefines.h"
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
#include <boost/signals2.hpp>
extern const BOOL ANIMATE;
@@ -56,6 +58,9 @@ class LLAgentAccess;
class LLSLURL;
class LLPauseRequestHandle;
class LLUIColor;
+class LLTeleportRequest;
+
+typedef boost::shared_ptr<LLTeleportRequest> LLTeleportRequestPtr;
//--------------------------------------------------------------------
// Types
@@ -539,7 +544,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 +562,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 +575,44 @@ 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();
+
+ //--------------------------------------------------------------------
+ // Teleport State
+ //--------------------------------------------------------------------
public:
ETeleportState getTeleportState() const { return mTeleportState; }
void setTeleportState(ETeleportState state);
@@ -614,8 +655,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 +670,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 +699,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);
diff --git a/indra/newview/llagentaccess.cpp b/indra/newview/llagentaccess.cpp
index 08a33ab04a..c4ee321e04 100644
--- 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
--- 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/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
new file mode 100644
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 100644
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/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index faadfb4b87..06a9892c7e 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -52,7 +52,8 @@
std::string self_av_string()
{
- return gAgentAvatarp->avString();
+ // On logout gAgentAvatarp can already be invalid
+ return isAgentAvatarValid() ? gAgentAvatarp->avString() : "";
}
// RAII thingy to guarantee that a variable gets reset when the Setter
@@ -229,12 +230,13 @@ LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit
LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
{
- LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
-
- selfStopPhase("update_appearance_on_destroy");
-
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);
}
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ed04b5bf38..aa465b7a75 100644
--- 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
@@ -89,11 +89,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"
// Linden library includes
#include "llavatarnamecache.h"
@@ -107,17 +109,19 @@
#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"
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
-
+#include <boost/algorithm/string.hpp>
#if LL_WINDOWS
@@ -215,6 +219,7 @@
#include "llmachineid.h"
#include "llmainlooprepeater.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
@@ -318,7 +323,7 @@ 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 ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
@@ -375,6 +380,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");
}
//----------------------------------------------------------------------------
@@ -618,13 +626,14 @@ LLTextureFetch* LLAppViewer::sTextureFetch = NULL;
LLAppViewer::LLAppViewer() :
mMarkerFile(),
- mLogoutMarkerFile(NULL),
+ mLogoutMarkerFile(),
mReportedCrash(false),
mNumSessions(0),
mPurgeCache(false),
mPurgeOnExit(false),
mSecondInstance(false),
mSavedFinalSnapshot(false),
+ mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
mForceGraphicsDetail(false),
mQuitRequested(false),
mLogoutRequestSent(false),
@@ -675,12 +684,15 @@ bool LLAppViewer::init()
// 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();
@@ -698,7 +710,7 @@ bool LLAppViewer::init()
//set the max heap size.
initMaxHeapSize() ;
- 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, "");
@@ -723,6 +735,10 @@ bool LLAppViewer::init()
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"),
@@ -764,12 +780,15 @@ bool LLAppViewer::init()
&LLUI::sGLScaleFactor);
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 LLTrans after LLUI::initClass has been called.
+ initStrings();
- // Setup notifications after LLUI::setupPaths() has been called.
+ // Setup notifications after LLUI::initClass() has been called.
LLNotifications::instance();
LL_INFOS("InitInfo") << "Notifications initialized." << LL_ENDL ;
@@ -1162,6 +1181,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");
@@ -1347,6 +1368,7 @@ bool LLAppViewer::mainLoop()
// yield some time to the os based on command line option
if(mYieldTime >= 0)
{
+ LLFastTimer t(FTM_YIELD);
ms_sleep(mYieldTime);
}
@@ -1602,6 +1624,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())
{
@@ -1796,6 +1821,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);
@@ -1860,6 +1892,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();
@@ -1867,8 +1900,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;
@@ -1937,12 +1982,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())
@@ -2225,10 +2264,8 @@ 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",
@@ -2542,13 +2579,28 @@ bool LLAppViewer::initConfiguration()
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");
- }
+ 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");
@@ -2631,14 +2683,6 @@ 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"))
- {
- LLStartUp::setStartSLURL(LLSLURL(gSavedSettings.getString("LoginLocation")));
- }
-
if (!gSavedSettings.getBOOL("AllowMultipleViewers"))
{
//
@@ -2686,12 +2730,27 @@ bool LLAppViewer::initConfiguration()
}
}
- // 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"))
+ && !clp.hasOption("url")
+ && !clp.hasOption("slurl"))
+ {
+ // 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");
@@ -2700,6 +2759,52 @@ bool LLAppViewer::initConfiguration()
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
@@ -3075,8 +3180,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
@@ -3101,8 +3206,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;
@@ -3230,22 +3335,27 @@ 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;
+ std::string crash_file_name = ( gLLErrorActivated )
+ ? gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LLERROR_MARKER_FILE_NAME)
+ : gDirUtilp->getExpandedFilename(LL_PATH_LOGS,ERROR_MARKER_FILE_NAME);
+ LL_INFOS("MarkerFile") << "Creating crash marker file " << crash_file_name << LL_ENDL;
LLAPRFile crash_file ;
crash_file.open(crash_file_name, LL_APR_W);
if (crash_file.getFileHandle())
{
LL_INFOS("MarkerFile") << "Created crash marker file " << crash_file_name << LL_ENDL;
+ recordMarkerVersion(crash_file);
}
else
{
LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_file_name << LL_ENDL;
}
}
+ else
+ {
+ LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
+ }
if (gMessageSystem && gDirUtilp)
{
@@ -3297,7 +3407,7 @@ bool LLAppViewer::anotherInstanceRunning()
// If the file is currently locked, that means another process is already running.
std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
- LL_DEBUGS("MarkerFile") << "Checking marker file for lock..." << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "Checking marker file '"<< marker_file << "' for lock..." << LL_ENDL;
//Freeze case checks
if (LLAPRFile::isExist(marker_file, NULL, LL_APR_RB))
@@ -3323,6 +3433,46 @@ bool LLAppViewer::anotherInstanceRunning()
return false;
}
+// 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: 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
+{
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::getChannelAndVersion());
+ char marker_version[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
+ LL_DEBUGS("MarkerFile") << "Compare markers: ";
+ std::string marker_string(marker_version, marker_version_length);
+ LL_CONT << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << LL_ENDL;
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ {
+ sameVersion = true;
+ }
+ marker_file.close();
+ }
+ return sameVersion;
+}
+
void LLAppViewer::initMarkerFile()
{
//First, check for the existence of other files.
@@ -3345,27 +3495,55 @@ void LLAppViewer::initMarkerFile()
if (LLAPRFile::isExist(mMarkerFileName, NULL, LL_APR_RB) && !anotherInstanceRunning())
{
- gLastExecEvent = LAST_EXEC_FROZE;
- LL_INFOS("MarkerFile") << "Exec marker found: program froze on previous execution" << LL_ENDL;
+ if ( markerIsSameVersion(mMarkerFileName) )
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_FROZE;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL;
+ }
}
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 crashed '"<< logout_marker_file << "', setting LastExecEvent to " << gLastExecEvent << 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);
}
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))
+ {
+ gLastExecEvent = ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
+ ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_LLERROR_CRASH;
+ LL_INFOS("MarkerFile") << "Last exec LLError '"<< llerror_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Last exec LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(llerror_marker_file);
}
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))
+ {
+ gLastExecEvent = (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
+ ? LAST_EXEC_LOGOUT_CRASH : LAST_EXEC_OTHER_CRASH;
+ LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Last exec '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL;
+ }
LLAPRFile::remove(error_marker_file);
}
@@ -3381,35 +3559,48 @@ void LLAppViewer::initMarkerFile()
if (s == APR_SUCCESS && mMarkerFile.getFileHandle())
{
- LL_DEBUGS("MarkerFile") << "Marker file created." << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "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") << "Marker file locked." << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS("MarkerFile") << "Marker file cannot be locked." << 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_INFOS("MarkerFile") << "Failed to create marker file '"<< mMarkerFileName << "'." << LL_ENDL;
}
-
- LL_DEBUGS("MarkerFile") << "Marker file locked." << LL_ENDL;
}
void LLAppViewer::removeMarkerFile(bool leave_logout_marker)
{
- LL_DEBUGS("MarkerFile") << "removeMarkerFile()" << LL_ENDL;
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile("<<leave_logout_marker<<")" << LL_ENDL;
if (mMarkerFile.getFileHandle())
{
- mMarkerFile.close() ;
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"'"<< LL_ENDL;
+ mMarkerFile.close();
LLAPRFile::remove( mMarkerFileName );
}
- if (mLogoutMarkerFile != NULL && !leave_logout_marker)
+ else
+ {
+ LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL;
+ }
+ if (!leave_logout_marker)
{
+ if (mLogoutMarkerFile.getFileHandle())
+ {
+ LL_DEBUGS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL;
+ mLogoutMarkerFile.close();
+ }
+ else
+ {
+ LL_WARNS("MarkerFile") << "removeMarkerFile marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL;
+ }
LLAPRFile::remove( mLogoutMarkerFileName );
- mLogoutMarkerFile = NULL;
}
}
@@ -3552,8 +3743,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))
@@ -3569,8 +3759,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++;
@@ -3801,7 +3991,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)
@@ -4312,6 +4502,10 @@ void LLAppViewer::idle()
{
return;
}
+ if (gTeleportDisplay)
+ {
+ return;
+ }
gViewerWindow->updateUI();
@@ -4610,16 +4804,15 @@ void LLAppViewer::sendLogoutRequest()
mLogoutMarkerFileName = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,LOGOUT_MARKER_FILE_NAME);
LLAPRFile outfile ;
- outfile.open(mLogoutMarkerFileName, LL_APR_W);
- mLogoutMarkerFile = outfile.getFileHandle() ;
- if (mLogoutMarkerFile)
+ mLogoutMarkerFile.open(mLogoutMarkerFileName, LL_APR_W);
+ if (mLogoutMarkerFile.getFileHandle())
{
- llinfos << "Created logout marker file " << mLogoutMarkerFileName << llendl;
- apr_file_close(mLogoutMarkerFile);
+ LL_INFOS("MarkerFile") << "Created logout marker file '"<< mLogoutMarkerFileName << "' " << mLogoutMarkerFileName << LL_ENDL;
+ recordMarkerVersion(outfile);
}
else
{
- llwarns << "Cannot create logout marker file " << mLogoutMarkerFileName << llendl;
+ LL_WARNS("MarkerFile") << "Cannot create logout marker file " << mLogoutMarkerFileName << LL_ENDL;
}
}
}
@@ -5009,6 +5202,10 @@ void LLAppViewer::handleLoginComplete()
mOnLoginCompleted();
writeDebugInfo();
+
+ // 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()
@@ -5026,7 +5223,7 @@ void LLAppViewer::launchUpdater()
#endif
// *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
@@ -5108,20 +5305,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 f7d019ccba..0cfedd8b2a 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -31,6 +31,7 @@
#include "llcontrol.h"
#include "llsys.h" // for LLOSInfo
#include "lltimer.h"
+#include "llappcorehttp.h"
class LLCommandLineParser;
class LLFrameTimer;
@@ -173,6 +174,9 @@ 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.
@@ -194,6 +198,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,7 +214,9 @@ private:
bool anotherInstanceRunning();
void initMarkerFile();
-
+ 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
@@ -229,7 +236,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;
@@ -247,6 +254,7 @@ private:
bool mPurgeOnExit;
bool mSavedFinalSnapshot;
+ bool mSavePerAccountSettings; // only save per account settings if login succeeded
bool mForceGraphicsDetail;
@@ -270,6 +278,9 @@ private:
boost::scoped_ptr<LLUpdaterService> mUpdater;
+ // llcorehttp library init/shutdown helper
+ LLAppCoreHttp mAppCoreHttp;
+
//---------------------------------------------
//*NOTE: Mani - legacy updater stuff
// Still useable?
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 48d02dfeaa..e8d8efdc0a 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -365,7 +365,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};
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index bad60a9757..11790d562f 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -125,11 +125,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
#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 +148,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
heap_enable_lfh_error[i] = GetLastError();
}
#endif
+#endif
// *FIX: global
gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 65bfc990d1..7b2c536f5a 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -919,7 +919,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 +949,7 @@ public:
void confirmUpload(
const std::string& confirmation_url,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
+ LLPointer<LLNewAgentInventoryVariablePriceResponder> responder)
{
if ( getFilename().empty() )
{
@@ -1124,7 +1124,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
// and cause sadness.
mImpl->confirmUpload(
confirmation_url,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
+ LLPointer<LLNewAgentInventoryVariablePriceResponder>(this));
}
else
{
@@ -1157,7 +1157,7 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
mImpl,
_1,
_2,
- boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
+ LLPointer<LLNewAgentInventoryVariablePriceResponder>(this)));
}
}
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index c9543988a6..ea0b8f00a4 100644
--- 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/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
new file mode 100644
index 0000000000..d71cf290d6
--- /dev/null
+++ b/indra/newview/llautoreplace.cpp
@@ -0,0 +1,811 @@
+/**
+ * @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"
+
+LLAutoReplace* LLAutoReplace::sInstance;
+
+const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
+
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+LLAutoReplace::~LLAutoReplace()
+{
+ sInstance = NULL;
+}
+
+void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
+{
+ static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
+ if(perform_autoreplace)
+ {
+ S32 wordEnd = cursorPos-1;
+ LLWString text = inputText.getWString();
+
+ bool atSpace = (text[wordEnd] == ' ');
+ bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+
+ if (atSpace || haveWord)
+ {
+ if (atSpace && wordEnd > 0)
+ {
+ // find out if this space immediately follows a word
+ wordEnd--;
+ haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+ }
+ if (haveWord)
+ {
+ // wordEnd points to the end of a word, now find the start of the word
+ std::string word;
+ S32 wordStart = wordEnd;
+ for ( S32 backOne = wordStart - 1;
+ backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]);
+ backOne--
+ )
+ {
+ wordStart--; // walk wordStart back to the beginning of the word
+ }
+ LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
+ std::string strText = std::string(text.begin(), text.end());
+ std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
+ std::string replacementWord( mSettings.replaceWord( lastWord ) );
+
+ if ( replacementWord != lastWord )
+ {
+ // The last word is one for which we have a replacement
+ if (atSpace)
+ {
+ // replace the last word in the input
+ LLWString strNew = utf8str_to_wstring(replacementWord);
+ LLWString strOld = utf8str_to_wstring(lastWord);
+ int size_change = strNew.size() - strOld.size();
+
+ text.replace(wordStart,lastWord.length(),strNew);
+ inputText = wstring_to_utf8str(text);
+ cursorPos+=size_change;
+ }
+ }
+ }
+ }
+ }
+}
+
+LLAutoReplace* LLAutoReplace::getInstance()
+{
+ if(!sInstance)
+ {
+ sInstance = new LLAutoReplace();
+ sInstance->loadFromSettings();
+ }
+ return sInstance;
+}
+
+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();
+}
+
+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.getAsLLSD(), 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");
+ 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::getAsLLSD()
+{
+ return mLists;
+}
+
+LLAutoReplaceSettings::~LLAutoReplaceSettings()
+{
+}
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
new file mode 100644
index 0000000000..f720cc4eda
--- /dev/null
+++ b/indra/newview/llautoreplace.h
@@ -0,0 +1,231 @@
+/**
+ * @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& getAsLLSD();
+ ///< @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 keyword is replaced by the associated value from the map.
+ *
+ * See the autoreplaceCallback method for how to add autoreplace functionality
+ * to a text entry tool.
+ */
+class LLAutoReplace : public LLSingleton<LLAutoReplace>
+{
+ public:
+ LLAutoReplace();
+ ~LLAutoReplace();
+
+ /// @return a pointer to the active instance
+ static LLAutoReplace* getInstance();
+
+ /// Callback that provides the hook for use in text entry methods
+ void autoreplaceCallback(LLUIString& inputText, S32& cursorPos);
+
+ /// 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>;
+ static LLAutoReplace* sInstance; ///< the active settings instance
+
+ 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/llchathistory.cpp b/indra/newview/llchathistory.cpp
index f530d10ddc..84e73e96fa 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -495,7 +495,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)
{
@@ -689,8 +689,11 @@ 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();
llassert(mEditor);
@@ -783,7 +786,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
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 + "] ", mEditor->getLength() != 0, timestamp_style);
if (utf8str_trim(chat.mFromName).size() != 0)
{
@@ -842,7 +845,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
else
{
view = getHeader(chat, style_params, args);
- if (mEditor->getText().size() == 0)
+ if (mEditor->getLength() == 0)
p.top_pad = 0;
else
p.top_pad = mTopHeaderPad;
diff --git a/indra/newview/lldaycyclemanager.cpp b/indra/newview/lldaycyclemanager.cpp
index 347a467a8b..8af2f4ea33 100644
--- 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/lldirpicker.h b/indra/newview/lldirpicker.h
index 2188b7edd0..682f9d6476 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -37,8 +37,8 @@
#include <Carbon/Carbon.h>
// AssertMacros.h does bad things.
+#include "fix_macros.h"
#undef verify
-#undef check
#undef require
#include <vector>
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 21b21c152a..4894d63e13 100644
--- 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;
}
@@ -403,6 +406,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,41 +427,27 @@ 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);
-
- if (mParent.notNull() && mParent->isActive() && warning_enabled)
- {
- LL_WARNS_ONCE("Drawable") << "Drawable becomes static with active parent!" << LL_ENDL;
- }
+ clearState(ACTIVE | ANIMATED_CHILD);
+ //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();
iter != child_list.end(); iter++)
@@ -483,8 +474,8 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
mSpatialBridge->markDead();
setSpatialBridge(NULL);
}
+ updatePartition();
}
- updatePartition();
}
// Returns "distance" between target destination and resulting xfrom
@@ -538,9 +529,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
@@ -549,15 +540,25 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
}
- 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 (!getVOVolume() && !isAvatar())
{
movePartition();
@@ -568,9 +569,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 +595,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();
+ }
}
}
@@ -621,9 +624,9 @@ BOOL LLDrawable::updateMove()
{
return FALSE;
}
-
+
makeActive();
-
+
BOOL done;
if (isState(MOVE_UNDAMPED))
@@ -651,7 +654,6 @@ BOOL LLDrawable::updateMoveUndamped()
}
mVObjp->clearChanged(LLXform::MOVED);
-
return TRUE;
}
@@ -703,6 +705,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 +734,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]);
@@ -771,18 +779,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 +807,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 +827,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 +944,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 +970,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 +1105,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
mDrawable = root;
root->setSpatialBridge(this);
+ mBinIndex = -1;
+
mRenderType = mDrawable->mRenderType;
mDrawableType = mDrawable->mRenderType;
@@ -1385,6 +1411,11 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
return;
}
+ if (gShiftFrame)
+ {
+ return;
+ }
+
if (mDrawable->getVObj())
{
if (mDrawable->getVObj()->isAttachment())
@@ -1462,6 +1493,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 +1511,7 @@ void LLSpatialBridge::cleanupReferences()
drawable->setSpatialGroup(NULL);
}
}
- }
+ }*/
LLDrawable* drawablep = mDrawable;
mDrawable = NULL;
@@ -1529,10 +1564,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..b1e32bdb5b 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -59,6 +59,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,6 +76,16 @@ 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);
@@ -109,6 +120,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; }
@@ -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
@@ -277,11 +291,13 @@ public:
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 +306,6 @@ public:
LLPointer<LLDrawable> mParent;
F32 mDistanceWRTCamera;
-
- S32 mQuietCount;
static S32 getCurrentFrame() { return sCurVisible; }
static S32 getMinVisFrameRange();
@@ -314,6 +328,7 @@ private:
mutable U32 mVisible;
F32 mRadius;
F32 mBinRadius;
+ mutable S32 mBinIndex;
S32 mGeneration;
LLVector3 mCurrentScale;
@@ -322,7 +337,7 @@ private:
static U32 sNumZombieDrawables;
static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList;
-};
+} LL_ALIGN_POSTFIX(16);
inline LLFace* LLDrawable::getFace(const S32 i) const
@@ -333,12 +348,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..94dd927d26 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -116,6 +116,7 @@ LLDrawPool::LLDrawPool(const U32 type)
sNumDrawPools++;
mId = sNumDrawPools;
mVertexShaderLevel = 0;
+ mSkipRender = false;
}
LLDrawPool::~LLDrawPool()
@@ -253,48 +254,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,7 +401,7 @@ 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)
@@ -460,6 +419,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++;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 64774d06df..ab9bb9e611 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -77,6 +77,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 +116,7 @@ protected:
S32 mVertexShaderLevel;
S32 mId;
U32 mType; // Type of draw pool
+ BOOL mSkipRender;
};
class LLRenderPass : public LLDrawPool
@@ -186,10 +190,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..313b310e1e 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -348,7 +348,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 &&
@@ -385,7 +385,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
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);
@@ -405,6 +405,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
{
LLDrawInfo& params = **k;
+ if ((params.mVertexBuffer->getTypeMask() & mask) != mask)
+ { //FIXME!
+ llwarns << "Missing required components, skipping render batch." << llendl;
+ continue;
+ }
+
LLRenderPass::applyModelMatrix(params);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 0103373fd2..0e15f474c9 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -261,7 +261,9 @@ void LLDrawPoolAvatar::beginPostDeferredAlpha()
sRenderingSkinned = TRUE;
gPipeline.bindDeferredShader(*sVertexProgram);
-
+
+ sVertexProgram->setMinimumAlpha(0.2f);
+
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
}
@@ -1034,9 +1036,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++)
@@ -1193,15 +1199,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass >= 7 && pass < 9)
{
- 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);
@@ -1217,20 +1214,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
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);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.setColorMask(false, true);
-
renderRiggedGlow(avatarp);
- gGL.setColorMask(true, false);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
return;
}
@@ -1428,7 +1413,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
- if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
+ if (avatar->isSelf() && !gAgent.needsRenderAvatar())
{
return;
}
@@ -1557,8 +1542,12 @@ void LLDrawPoolAvatar::renderDeferredRiggedBump(LLVOAvatar* avatar)
renderRigged(avatar, RIGGED_DEFERRED_BUMP);
}
+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)
{
@@ -1630,17 +1619,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/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 6f71e6ebc8..a264eae302 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -847,12 +847,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;
- for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
@@ -1448,10 +1448,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/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index b95d8296fa..9bc32fddbd 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -294,6 +294,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!
@@ -566,7 +595,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 +744,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 +784,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);
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 283ed87f1a..2163d087e1 100644
--- 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
--- 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/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index caf15fe1cb..b5faff7968 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -192,14 +192,18 @@ 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();
diff --git a/indra/newview/lldriverparam.cpp b/indra/newview/lldriverparam.cpp
index 64eb11fc9b..885cae1737 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/newview/lldriverparam.cpp
@@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
mAvatarp(avatarp),
mWearablep(NULL)
{
+ mDefaultVec.clear();
}
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
@@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) :
mAvatarp(NULL),
mWearablep(wearablep)
{
+ mDefaultVec.clear();
}
LLDriverParam::~LLDriverParam()
@@ -341,18 +343,19 @@ F32 LLDriverParam::getTotalDistortion()
return sum;
}
-const LLVector3 &LLDriverParam::getAvgDistortion()
+const LLVector4a &LLDriverParam::getAvgDistortion()
{
// It's not actually correct to take the average of averages, but it good enough here.
- LLVector3 sum;
+ LLVector4a sum;
+ sum.clear();
S32 count = 0;
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getAvgDistortion();
+ sum.add(driven->mParam->getAvgDistortion());
count++;
}
- sum /= (F32)count;
+ sum.mul( 1.f/(F32)count);
mDefaultVec = sum;
return mDefaultVec;
@@ -375,21 +378,22 @@ F32 LLDriverParam::getMaxDistortion()
}
-LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
+LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
{
- LLVector3 sum;
+ LLVector4a sum;
+ sum.clear();
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
- sum += driven->mParam->getVertexDistortion( index, poly_mesh );
+ sum.add(driven->mParam->getVertexDistortion( index, poly_mesh ));
}
return sum;
}
-const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
mCurrentDistortionParam = NULL;
- const LLVector3* v = NULL;
+ const LLVector4a* v = NULL;
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
{
LLDrivenEntry* driven = &(*iter);
@@ -404,7 +408,7 @@ const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly
return v;
};
-const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
llassert( mCurrentDistortionParam );
if( !mCurrentDistortionParam )
@@ -432,7 +436,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_
}
// 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 );
+ 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
diff --git a/indra/newview/lldriverparam.h b/indra/newview/lldriverparam.h
index fb1b44458c..c0976d1d43 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/newview/lldriverparam.h
@@ -83,6 +83,16 @@ public:
LLDriverParam(LLWearable *wearablep);
~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
@@ -105,18 +115,18 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
+ /*virtual*/ const LLVector4a& 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);
+ /*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);
protected:
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
- LLVector3 mDefaultVec; // temp holder
+ LLVector4a mDefaultVec; // temp holder
typedef std::vector<LLDrivenEntry> entry_list_t;
entry_list_t mDriven;
LLViewerVisualParam* mCurrentDistortionParam;
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index bf8338e5f2..fa42b157a7 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -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,14 +216,12 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
return TRUE;
}
-#if 0 //THIS CAUSES MAINT-1092
- bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete();
+ bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI;
if (use_fbo)
{
gPipeline.mWaterDis.bindTarget();
}
-#endif
LLGLSLShader::bindNoShader();
LLVertexBuffer::unbind();
@@ -258,12 +256,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
}
}
-#if 0
if (use_fbo)
{
gPipeline.mWaterDis.flush();
}
-#endif
return ret;
}
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index e18090545d..c51e7d1e1a 100644
--- 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,
@@ -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/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 4f4d9a40b4..2c786b7f8b 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -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)
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4108d69e82..605cb81c10 100644..100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -44,11 +44,14 @@
#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"
+
#define LL_MAX_INDICES_COUNT 1000000
@@ -56,7 +59,6 @@ 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
@@ -161,7 +163,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mGeomCount = 0;
mGeomIndex = 0;
mIndicesCount = 0;
- mIndicesIndex = 0;
+
+ //special value to indicate uninitialized position
+ mIndicesIndex = 0xFFFFFFFF;
+
mIndexInTex = 0;
mTexture = NULL;
mTEOffset = -1;
@@ -177,12 +182,6 @@ 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 ;
@@ -203,6 +202,12 @@ void LLFace::destroy()
mTexture->removeFace(this) ;
}
+ if (isState(LLFace::PARTICLE))
+ {
+ LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
+ clearState(LLFace::PARTICLE);
+ }
+
if (mDrawPoolp)
{
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
@@ -313,7 +318,20 @@ void LLFace::setTexture(LLViewerTexture* tex)
void LLFace::dirtyTexture()
{
- gPipeline.markTextured(getDrawable());
+ LLDrawable* drawablep = getDrawable();
+
+ if (mVObjp.notNull() && mVObjp->getVolume() &&
+ mTexture.notNull() && mTexture->getComponents() == 4)
+ { //dirty texture on an alpha object should be treated as an LoD update
+ LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj)
+ {
+ vobj->mLODChanged = TRUE;
+ }
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
+ }
+
+ gPipeline.markTextured(drawablep);
}
void LLFace::switchTexture(LLViewerTexture* new_texture)
@@ -372,7 +390,6 @@ void LLFace::setSize(S32 num_vertices, S32 num_indices, bool align)
mGeomCount = num_vertices;
mIndicesCount = num_indices;
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
llassert(verify());
@@ -765,12 +782,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
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;
@@ -1032,30 +1043,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 +1062,11 @@ bool LLFace::canRenderAsMask()
}
const LLTextureEntry* te = getTextureEntry();
-
+ if( !te || !getViewerObject() || !getTexture() )
+ {
+ 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 +1092,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_BINORMAL | 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<LLVector3> f_binorm;
+ LLStrider<LLVector3> f_norm;
+ LLStrider<LLVector2> f_tc;
+
+ buff->getBinormalStrider(f_binorm);
+ 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_binorm++).set(vf.mBinormals[i].getF32ptr());
+ *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");
@@ -1111,7 +1176,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,21 +1203,25 @@ 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;
}
}
@@ -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,757 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
{
do_xform = false;
}
+ }
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
+ if (use_transform_feedback &&
+ 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
+
+ LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
+
+ if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
+ {
+ mVObjp->getVolume()->genBinormals(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_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("texture_index_in", 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_COLOR);
+ gTransformColorProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
+
+ S32 val = *((S32*) color.mV);
+
+ gTransformColorProgram.uniform1i("color_in", 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_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("color_in", 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_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_binormal)
{
- bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
+ LLFastTimer t(FTM_FACE_GEOM_BINORMAL);
+ gTransformBinormalProgram.bind();
+
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_BINORMAL, mGeomIndex, mGeomCount);
+
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_BINORMAL);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
}
-
- if (bump_code)
+
+ if (rebuild_tcoord)
{
- mVObjp->getVolume()->genBinormals(f);
- F32 offset_multiple;
- switch( bump_code )
- {
- case BE_NO_BUMP:
- offset_multiple = 0.f;
- break;
- case BE_BRIGHTNESS:
- case BE_DARKNESS:
- if( mTexture.notNull() && mTexture->hasGLTexture())
- {
- // 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;
- }
- else
- {
- offset_multiple = 1.f/256;
- }
- break;
+ LLFastTimer t(FTM_FACE_GEOM_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();
- default: // Standard bumpmap textures. Assumed to be 256x256
- offset_multiple = 1.f / 256;
- break;
- }
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- F32 s_scale = 1.f;
- F32 t_scale = 1.f;
- if( tep )
+ if (do_bump)
{
- tep->getScale( &s_scale, &t_scale );
- }
- // 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);
+ mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
+ glBeginTransformFeedback(GL_POINTS);
+ buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
+ push_for_transform(buff, vf.mNumVertices, mGeomCount);
+ glEndTransformFeedback();
+ }
}
- U8 texgen = getTextureEntry()->getTexGen();
- if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- { //planar texgen needs binormals
- mVObjp->getVolume()->genBinormals(f);
+ 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);
- U8 tex_mode = 0;
-
- if (isState(TEXTURE_ANIM))
+ if (rebuild_tcoord)
{
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
+ 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);
- if (!tex_mode)
+ LLQuaternion bump_quat;
+ if (mDrawablep->isActive())
{
- clearState(TEXTURE_ANIM);
+ bump_quat = LLQuaternion(mDrawablep->getRenderMatrix());
}
- else
+
+ if (bump_code)
{
- os = ot = 0.f;
- r = 0.f;
- cos_ang = 1.f;
- sin_ang = 0.f;
- ms = mt = 1.f;
+ mVObjp->getVolume()->genBinormals(f);
+ F32 offset_multiple;
+ switch( bump_code )
+ {
+ case BE_NO_BUMP:
+ offset_multiple = 0.f;
+ break;
+ case BE_BRIGHTNESS:
+ case BE_DARKNESS:
+ if( mTexture.notNull() && mTexture->hasGLTexture())
+ {
+ // 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;
+ }
+ else
+ {
+ offset_multiple = 1.f/256;
+ }
+ break;
- do_xform = false;
+ default: // Standard bumpmap textures. Assumed to be 256x256
+ offset_multiple = 1.f / 256;
+ break;
+ }
+
+ F32 s_scale = 1.f;
+ F32 t_scale = 1.f;
+ if( tep )
+ {
+ tep->getScale( &s_scale, &t_scale );
+ }
+ // 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);
}
- if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
- { //don't override texture transform during tc bake
- tex_mode = 0;
+ U8 texgen = getTextureEntry()->getTexGen();
+ if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ { //planar texgen needs binormals
+ mVObjp->getVolume()->genBinormals(f);
}
- }
- LLVector4a scalea;
- scalea.load3(scale.mV);
+ U8 tex_mode = 0;
+
+ if (isState(TEXTURE_ANIM))
+ {
+ LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
+ tex_mode = vobj->mTexAnimMode;
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- bool do_tex_mat = tex_mode && mTextureMatrix;
+ 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 (!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);
+ do_xform = false;
+ }
- if (texgen != LLTextureEntry::TEX_GEN_PLANAR)
- {
- LLFastTimer t(FTM_FACE_TEX_QUICK);
- if (!do_tex_mat)
+ if (getVirtualSize() >= MIN_TEX_ANIM_SIZE)
+ { //don't override texture transform during tc bake
+ tex_mode = 0;
+ }
+ }
+
+ LLVector4a scalea;
+ scalea.load3(scale.mV);
+
+ bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
+ bool do_tex_mat = tex_mode && mTextureMatrix;
+
+ 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);
+
+ 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_coords.get(), (F32*) vf.mTexCoords, tc_size);
+ }
+ else
+ {
+ LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM);
+ F32* dst = (F32*) tex_coords.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 atlas, 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_coords++ = 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, 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);
- 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_coords++ = 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_coords++ = tc;
+ }
}
}
- }
- if (map_range)
- {
- mVertexBuffer->flush();
+ 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);
+ 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;
+ std::vector<LLVector2> bump_tc;
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
- LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& norm = vf.mNormals[i];
- LLVector4a& center = *(vf.mCenter);
+ LLVector4a& center = *(vf.mCenter);
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a vec = vf.mPositions[i];
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a vec = vf.mPositions[i];
- vec.mul(scalea);
+ vec.mul(scalea);
+
+ 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;
+ }
+ }
- switch (texgen)
+ if (tex_mode && mTextureMatrix)
{
- case LLTextureEntry::TEX_GEN_PLANAR:
- 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];
+ }
+ else
+ {
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ }
+
+ if(in_atlas)
+ {
+ //
+ //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())
+ {
+ 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;
+ }
+
+ 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 LLTextureEntry::TEX_GEN_SPHERICAL:
- sphericalProjection(tc, norm, center, vec);
+ 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
+ {
+ tc.mV[0] -= int_part ;
+ }
+
+ 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] ;
+ }
+ else //even number
+ {
+ tc.mV[1] -= int_part ;
+ }
break;
- case LLTextureEntry::TEX_GEN_CYLINDRICAL:
- cylindricalProjection(tc, norm, center, vec);
+ 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)
+ {
+ tc.mV[0] = 1.0f + tc.mV[0] ;
+ }
+ if(tc.mV[1] < 0.f)
+ {
+ tc.mV[1] = 1.0f + tc.mV[1] ;
+ }
break;
default:
break;
- }
- }
+ }
+
+ tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ;
+ tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ;
+ }
+
- 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];
+ *tex_coords++ = tc;
+ if (do_bump)
+ {
+ bump_tc.push_back(tc);
+ }
}
- else
+
+ if (map_range)
{
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ mVertexBuffer->flush();
}
- if(in_atlas)
+ if (do_bump)
{
- //
- //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())
+ mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
+
+ for (S32 i = 0; i < num_vertices; i++)
{
- 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;
- }
-
- 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
+ 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())
{
- tc.mV[0] -= int_part ;
+ LLVector3 t;
+ t.set(binormal.getF32ptr());
+ t *= bump_quat;
+ binormal.load3(t.mV);
}
- 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] ;
- }
- else //even number
- {
- tc.mV[1] -= int_part ;
- }
- 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)
- {
- tc.mV[0] = 1.0f + tc.mV[0] ;
- }
- if(tc.mV[1] < 0.f)
- {
- tc.mV[1] = 1.0f + tc.mV[1] ;
- }
- break;
- default:
- break;
+ 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() );
+
+ *tex_coords2++ = tc;
}
-
- 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)
- {
- bump_tc.push_back(tc);
- }
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
-
- if (do_bump)
- {
- mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range);
-
- for (S32 i = 0; i < num_vertices; i++)
- {
- 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())
+ if (map_range)
{
- LLVector3 t;
- t.set(binormal.getF32ptr());
- t *= bump_quat;
- binormal.load3(t.mV);
+ mVertexBuffer->flush();
}
-
- 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() );
-
- *tex_coords2++ = tc;
- }
-
- if (map_range)
- {
- mVertexBuffer->flush();
}
}
}
- }
- if (rebuild_pos)
- {
- LLFastTimer t(FTM_FACE_GEOM_POSITION);
- llassert(num_vertices > 0);
+ if (rebuild_pos)
+ {
+ 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);
-
- LLVector4a* src = vf.mPositions;
- volatile F32* dst = (volatile F32*) vert.get();
+ LLMatrix4a mat_vert;
+ mat_vert.loadu(mat_vert_in);
- volatile F32* end = dst+num_vertices*4;
- LLVector4a res;
+ LLVector4a* src = vf.mPositions;
+ volatile F32* dst = (volatile F32*) vert.get();
- LLVector4a texIdx;
+ volatile F32* end = dst+num_vertices*4;
+ LLVector4a res;
- 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);
-
- {
- LLFastTimer t(FTM_FACE_POSITION_STORE);
- LLVector4a tmp;
+ texIdx.set(0,0,0,val);
- do
- {
- mat_vert.affineTransform(*src++, res);
- tmp.setSelectWithMask(mask, texIdx, res);
- tmp.store4a((F32*) dst);
- dst += 4;
+ {
+ 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;
+ }
+ while(dst < end);
}
- 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);
+ S32 aligned_pad_vertices = mGeomCount - num_vertices;
+ res.set(res[0], res[1], res[2], 0.f);
+
+ while (aligned_pad_vertices > 0)
+ {
+ --aligned_pad_vertices;
+ res.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();
+ 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;
- }
+ 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)
- {
- mVertexBuffer->flush();
+ 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();
+ 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;
- }
+ 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)
- {
- mVertexBuffer->flush();
+ 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);
+ U32 glow32 = glow |
+ (glow << 8) |
+ (glow << 16) |
+ (glow << 24);
- U32 vec[4];
- vec[0] = vec[1] = vec[2] = vec[3] = glow32;
+ 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 +2151,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
- mLastVertexBuffer = mVertexBuffer;
- mLastGeomCount = mGeomCount;
- mLastGeomIndex = mGeomIndex;
- mLastIndicesCount = mIndicesCount;
- mLastIndicesIndex = mIndicesIndex;
-
return TRUE;
}
@@ -1959,6 +2172,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;
@@ -2024,8 +2243,17 @@ 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);
+ 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
@@ -2516,7 +2744,6 @@ void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
void LLFace::clearVertexBuffer()
{
mVertexBuffer = NULL;
- mLastVertexBuffer = NULL;
}
//static
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 82e4ab61b7..de4d03351c 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -59,6 +59,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 +90,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(); }
@@ -204,6 +218,7 @@ public:
F32 getTextureVirtualSize() ;
F32 getImportanceToCamera()const {return mImportanceToCamera ;}
+ void resetVirtualSize();
void setHasMedia(bool has_media) { mHasMedia = has_media ;}
BOOL hasMedia() const ;
@@ -222,7 +237,7 @@ public:
//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;
@@ -255,8 +270,7 @@ public:
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mLastVertexBuffer;
-
+
U32 mState;
LLFacePool* mDrawPoolp;
U32 mPoolType;
@@ -269,12 +283,6 @@ private:
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;
-
LLXformMatrix* mXform;
LLPointer<LLViewerTexture> mTexture;
LLPointer<LLDrawable> mDrawablep;
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 575b613ccf..4cbc9cab4a 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1191,7 +1191,7 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
}
else if (action == "paste")
{
- pastFromClipboard();
+ pasteFromClipboard();
}
else if (action == "delete")
{
@@ -1239,7 +1239,7 @@ BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
return TRUE;
}
-void LLFavoritesBarCtrl::pastFromClipboard() const
+void LLFavoritesBarCtrl::pasteFromClipboard() const
{
LLInventoryModel* model = &gInventory;
if(model && isClipboardPasteable())
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2f75b3bb0e..447d30f1f4 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -90,7 +90,7 @@ protected:
bool enableSelected(const LLSD& userdata);
void doToSelected(const LLSD& userdata);
BOOL isClipboardPasteable() const;
- void pastFromClipboard() const;
+ void pasteFromClipboard() const;
void showDropDownMenu();
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ec2493dd2e..2b39b771e7 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -57,6 +57,7 @@
#include "lldxhardware.h"
#endif
+#define LL_EXPORT_GPU_TABLE 0
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
@@ -386,6 +387,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 +419,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 +440,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 +473,18 @@ 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);
}
}
+#if LL_EXPORT_GPU_TABLE
+ json << "];\n\n";
+ json.close();
+#endif
file.close();
if ( gpuFound )
@@ -469,6 +499,10 @@ 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
}
// responder saves table into file
@@ -585,7 +619,7 @@ void LLFeatureManager::applyRecommendedSettings()
{
// apply saved settings
// cap the level at 2 (high)
- S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_2));
+ S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
llinfos << "Applying Recommended Features" << llendl;
@@ -680,12 +714,21 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
}
break;
case 1:
- maskFeatures("Mid");
+ maskFeatures("LowMid");
break;
case 2:
- maskFeatures("High");
+ maskFeatures("Mid");
break;
case 3:
+ maskFeatures("MidHigh");
+ break;
+ case 4:
+ maskFeatures("High");
+ break;
+ case 5:
+ maskFeatures("HighUltra");
+ break;
+ case 6:
maskFeatures("Ultra");
break;
default:
@@ -697,6 +740,7 @@ void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
LLViewerShaderMgr::sSkipReload = false;
LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.refreshCachedSettings();
}
void LLFeatureManager::applyBaseMasks()
@@ -714,14 +758,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;
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index c9cb397fcc..6f9d2e49c6 100644
--- 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;
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 8986a694f9..4bf5b26b3b 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -59,6 +59,7 @@ 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
//
@@ -218,6 +219,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;
@@ -643,6 +648,16 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB
result = false;
}
}
+ else if (filter == FFLOAD_DICTIONARY)
+ {
+ if (fileInfo.filetype != 'DIC ' &&
+ fileInfo.filetype != 'XCU ' &&
+ (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("dic"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) &&
+ fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("xcu"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)))
+ {
+ result = false;
+ }
+ }
if (fileInfo.extension)
{
@@ -1235,6 +1250,12 @@ 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)");
+}
+
BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
{
BOOL rtn = FALSE;
@@ -1371,6 +1392,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;
}
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index a4d5d68ff5..4f602f63f1 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -39,8 +39,8 @@
#include <Carbon/Carbon.h>
// AssertMacros.h does bad things.
+#include "fix_macros.h"
#undef verify
-#undef check
#undef require
#include <vector>
@@ -85,6 +85,7 @@ public:
FFLOAD_MODEL = 9,
FFLOAD_COLLADA = 10,
FFLOAD_SCRIPT = 11,
+ FFLOAD_DICTIONARY = 12
};
enum ESaveFilter
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 32a533570a..28d195d5e9 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -44,6 +44,8 @@
#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");
@@ -65,13 +67,50 @@ LLVolumeImplFlexible::LLVolumeImplFlexible(LLViewerObject* vo, LLFlexibleObjectD
mFrameNum = 0;
mCollisionSphereRadius = 0.f;
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();
@@ -255,50 +294,28 @@ 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)
-{
- if (mVO->mDrawable.isNull())
- {
- // Don't do anything until we have a drawable
- return FALSE; // (we are not initialized or updated)
- }
-
- BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
- //flexible objects never go static
- mVO->mDrawable->mQuietCount = 0;
- if (!mVO->mDrawable->isRoot())
- {
- LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
- parent->mDrawable->mQuietCount = 0;
- }
+void LLVolumeImplFlexible::updateRenderRes()
+{
+ LLDrawable* drawablep = mVO->mDrawable;
- 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,76 @@ 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)
- {
- gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
- }
- else if (visible &&
- !mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
- mVO->getPixelArea() > 256.f)
+ if (drawablep)
{
- U32 id;
- F32 pixel_area = mVO->getPixelArea();
-
- if (mVO->isRootEdit())
- {
- id = mID;
- }
- else
+ //LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
+
+ //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 ((mSimulateRes == 0) && visible)
+ {
+ updateRenderRes();
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ }
+ else
+ {
+ F32 pixel_area = mVO->getPixelArea();
+
+ U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+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) &&
+ mVO->getPixelArea() > 256.f)
+ {
+ U32 id;
+
+ 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,8 +418,11 @@ 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
}
@@ -380,6 +433,15 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
//the object is not visible
return ;
}
+
+ // stinson 11/12/2012: Need to check with davep on the following.
+ // 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;
@@ -729,7 +791,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 +880,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
--- 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/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
new file mode 100644
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 100644
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/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index ac33a05f42..62848586cd 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -422,13 +422,14 @@ void LLFloaterBvhPreview::resetMotion()
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);
@@ -438,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();
@@ -1124,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/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
index fd9c37ae73..4cb632bd6a 100644
--- 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/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 92ee8ddac6..6b2492d927 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -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();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index ee18c95b34..55f3d548ec 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -1865,23 +1865,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 +1886,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
@@ -2226,8 +2212,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 +2226,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 +2362,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
@@ -2394,7 +2379,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 +2418,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 +2466,7 @@ void LLPanelLandAccess::refresh()
}
mListBanned->addNameItem(entry.mID, ADD_DEFAULT, TRUE, suffix);
}
+ mListBanned->sortByName(TRUE);
}
if(parcel->getRegionDenyAnonymousOverride())
@@ -2608,13 +2602,13 @@ void LLPanelLandAccess::refresh_ui()
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);
}
}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 7448f2bb2a..a071f338ba 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -396,7 +396,6 @@ mCalculateBtn(NULL)
sInstance = this;
mLastMouseX = 0;
mLastMouseY = 0;
- mGLName = 0;
mStatusLock = new LLMutex(NULL);
mModelPreview = NULL;
@@ -498,7 +497,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 +537,6 @@ LLFloaterModelPreview::~LLFloaterModelPreview()
delete mModelPreview;
}
- if (mGLName)
- {
- LLImageGL::deleteTextures(1, &mGLName );
- }
-
delete mStatusLock;
mStatusLock = NULL;
}
@@ -4780,7 +4774,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)
@@ -5053,15 +5048,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();
@@ -5531,6 +5518,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 +5601,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
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index 64324854a5..ab319c30d5 100644
--- 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;
@@ -390,9 +389,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/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/llfloaterpathfindingcharacters.cpp b/indra/newview/llfloaterpathfindingcharacters.cpp
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 173b0e538c..542e96cf16 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"
@@ -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"
@@ -346,7 +346,9 @@ 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.AutoReplace", boost::bind(&LLFloaterPreference::onClickAutoReplace, this));
+ mCommitCallbackRegistrar.add("Pref.SpellChecker", boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
+
sSkin = gSavedSettings.getString("SkinCurrent");
mCommitCallbackRegistrar.add("Pref.ClickActionChange", boost::bind(&LLFloaterPreference::onClickActionChange, this));
@@ -354,7 +356,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
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 );
}
@@ -435,6 +437,8 @@ BOOL LLFloaterPreference::postBuild()
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();
@@ -604,6 +608,9 @@ void LLFloaterPreference::cancel()
// hide translation settings floater
LLFloaterReg::hideInstance("prefs_translation");
+ // hide translation settings floater
+ LLFloaterReg::hideInstance("prefs_autoreplace");
+
// cancel hardware menu
LLFloaterHardwareSettings* hardware_settings = LLFloaterReg::getTypedInstance<LLFloaterHardwareSettings>("prefs_hardware_settings");
if (hardware_settings)
@@ -625,6 +632,13 @@ 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)
@@ -736,7 +750,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()
@@ -772,7 +789,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
@@ -789,7 +814,7 @@ void LLFloaterPreference::onBtnApply( )
apply();
saveSettings();
- LLPanelLogin::updateLocationCombo( false );
+ LLPanelLogin::updateLocationSelectorsVisibility();
}
// static
@@ -931,7 +956,6 @@ void LLFloaterPreference::refreshSkin(void* data)
self->getChild<LLRadioGroup>("skin_selection", true)->setValue(sSkin);
}
-
void LLFloaterPreference::buildPopupLists()
{
LLScrollListCtrl& disabled_popups =
@@ -1515,6 +1539,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;
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ec5994e917..b71f7c647b 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -157,6 +157,8 @@ public:
void onClickBlockList();
void onClickProxySettings();
void onClickTranslationSettings();
+ void onClickAutoReplace();
+ void onClickSpellChecker();
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 17850ff35d..fe29bb38c7 100644
--- 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());
}
@@ -1924,10 +1923,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 +1942,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 +1987,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 +2086,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();
}
@@ -2225,47 +2216,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 +2229,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
@@ -2792,15 +2710,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 +2735,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 +2744,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);
}
}
@@ -2849,15 +2768,16 @@ bool LLDispatchSetEstateAccess::operator()(
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);
}
}
@@ -2872,6 +2792,9 @@ bool LLDispatchSetEstateAccess::operator()(
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 +2806,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
--- 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/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
new file mode 100644
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 100644
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/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp
index 2b34b72055..9157389187 100644
--- a/indra/newview/llfloatertexturefetchdebugger.cpp
+++ b/indra/newview/llfloatertexturefetchdebugger.cpp
@@ -59,12 +59,15 @@ LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
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;
@@ -76,8 +79,10 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)
mButtonStateMap["decode_btn"] = false;
mButtonStateMap["gl_btn"] = false;
- mButtonStateMap["refetchviscache_btn"] = true;
- mButtonStateMap["refetchvishttp_btn"] = true;
+ mButtonStateMap["refetchviscache_btn"] = false;
+ mButtonStateMap["refetchvishttp_btn"] = false;
+ mButtonStateMap["refetchallcache_btn"] = false;
+ mButtonStateMap["refetchallhttp_btn"] = false;
updateButtons();
@@ -89,7 +94,7 @@ BOOL LLFloaterTextureFetchDebugger::postBuild(void)
LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
{
//stop everything
- mDebugger->stopDebug();
+ mDebugger->setStopDebug();
}
void LLFloaterTextureFetchDebugger::updateButtons()
@@ -118,47 +123,81 @@ void LLFloaterTextureFetchDebugger::disableButtons()
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()
{
- LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
-
- if(mDebugger->update())
+ 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::READ_CACHE:
- mButtonStateMap["cachewrite_btn"] = true;
- mButtonStateMap["decode_btn"] = true;
- updateButtons();
+ 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::WRITE_CACHE:
- updateButtons();
+ case LLTextureFetchDebugger::READ_CACHE:
+ mButtonStateMap["decode_btn"] = true;
+ break;
+ case LLTextureFetchDebugger::WRITE_CACHE:
break;
case LLTextureFetchDebugger::DECODING:
- mButtonStateMap["gl_btn"] = true;
- updateButtons();
+ mButtonStateMap["gl_btn"] = true;
break;
case LLTextureFetchDebugger::HTTP_FETCHING:
mButtonStateMap["cacheread_btn"] = true;
mButtonStateMap["cachewrite_btn"] = true;
- mButtonStateMap["decode_btn"] = true;
- updateButtons();
+ mButtonStateMap["decode_btn"] = true;
break;
- case LLTextureFetchDebugger::GL_TEX:
- updateButtons();
+ case LLTextureFetchDebugger::GL_TEX:
break;
- case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
- updateButtons();
- case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
- updateButtons();
+ 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();
+ }
}
}
@@ -172,11 +211,10 @@ void LLFloaterTextureFetchDebugger::onClickStart()
{
disableButtons();
- mDebugger->startDebug();
+ setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);
mButtonStateMap["start_btn"] = false;
- mButtonStateMap["cacheread_btn"] = true;
- mButtonStateMap["http_btn"] = true;
+
updateButtons();
}
@@ -185,7 +223,9 @@ void LLFloaterTextureFetchDebugger::onClickClose()
setVisible(FALSE);
//stop everything
- mDebugger->stopDebug();
+ mDebugger->setStopDebug();
+
+ delete this;
}
void LLFloaterTextureFetchDebugger::onClickClear()
@@ -203,7 +243,7 @@ void LLFloaterTextureFetchDebugger::onClickClear()
updateButtons();
//stop everything
- mDebugger->stopDebug();
+ mDebugger->setStopDebug();
mDebugger->clearHistory();
}
@@ -211,49 +251,63 @@ void LLFloaterTextureFetchDebugger::onClickCacheRead()
{
disableButtons();
- mDebugger->debugCacheRead();
+ setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);
}
void LLFloaterTextureFetchDebugger::onClickCacheWrite()
{
disableButtons();
- mDebugger->debugCacheWrite();
+ setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);
}
void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
{
disableButtons();
- mDebugger->debugHTTP();
+ setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);
}
void LLFloaterTextureFetchDebugger::onClickDecode()
{
disableButtons();
- mDebugger->debugDecoder();
+ setStartStatus((S32)LLTextureFetchDebugger::DECODING);
}
void LLFloaterTextureFetchDebugger::onClickGLTexture()
{
disableButtons();
- mDebugger->debugGLTextureCreation();
+ setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);
}
void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
{
disableButtons();
- mDebugger->debugRefetchVisibleFromCache();
+ setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);
}
void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
{
disableButtons();
- mDebugger->debugRefetchVisibleFromHTTP();
+ 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()
@@ -368,8 +422,22 @@ void LLFloaterTextureFetchDebugger::draw()
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->getRefetchedData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
+ 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
@@ -382,8 +450,22 @@ void LLFloaterTextureFetchDebugger::draw()
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->getRefetchedData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedPixels() / 1000000.f));
+ 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
index 33012c6a3d..096ad88e07 100644
--- a/indra/newview/llfloatertexturefetchdebugger.h
+++ b/indra/newview/llfloatertexturefetchdebugger.h
@@ -53,6 +53,8 @@ public:
void onClickRefetchVisCache();
void onClickRefetchVisHTTP();
+ void onClickRefetchAllCache();
+ void onClickRefetchAllHTTP();
public:
void idle() ;
@@ -63,9 +65,12 @@ private:
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..48484786f6 100644
--- 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);
@@ -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
@@ -1218,7 +1197,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
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 87d048c15b..2d91a61b54 100644
--- 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,13 +187,14 @@ 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);
@@ -215,28 +210,33 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
// ...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";
+ 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 +260,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 +301,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 +481,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
--- 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
--- 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/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index d741b5b133..15e0b89f6c 100644
--- 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,21 @@ 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
+ 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?)
}
if(ID == 1)
@@ -964,7 +904,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/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 1fa194ab19..8e540a0cc8 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -562,7 +562,6 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
{
width = scroll_rect.getWidth();
}
-
LLView::reshape(width, height, called_from_parent);
mReshapeSignal(mSelectedItems, FALSE);
}
@@ -2235,11 +2234,9 @@ void LLFolderView::doIdle()
mDebugFilters = debug_filters;
arrangeAll();
}
-
- if (mFilter->isModified() && mFilter->isNotDefault())
- {
- mNeedsAutoSelect = TRUE;
- }
+ BOOL filter_modified_and_active = mFilter->isModified() && mFilter->isNotDefault();
+ mNeedsAutoSelect = filter_modified_and_active &&
+ !(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
mFilter->clearModified();
// filter to determine visibility before arranging
@@ -2251,7 +2248,7 @@ void LLFolderView::doIdle()
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()))
+ if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->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
@@ -2261,7 +2258,7 @@ void LLFolderView::doIdle()
// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
// Used by LLPlacesFolderView.
- if (mAutoSelectOverride && !mFilter->getFilterSubString().empty())
+ if (!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
@@ -2553,6 +2550,25 @@ void LLFolderView::onRenamerLost()
}
}
+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;
+}
+
LLInventoryFilter* LLFolderView::getFilter()
{
return mFilter;
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index da8bb15f8e..3f78312a98 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -207,6 +207,8 @@ public:
virtual void doDelete();
virtual BOOL canDoDelete() const;
+ LLFolderViewItem* getNextUnselectedItem();
+
// Public rename functionality - can only start the process
void startRenamingSelectedItem( void );
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 515e544452..3aa16b4413 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -1098,6 +1098,10 @@ void LLFolderViewItem::draw()
}
}
+bool LLFolderViewItem::isInSelection() const
+{
+ return mIsSelected || (mParentFolder && mParentFolder->isInSelection());
+}
///----------------------------------------------------------------------------
/// Class LLFolderViewFolder
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 3c7592046a..577b6b54a2 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -243,6 +243,7 @@ public:
virtual void destroyView();
BOOL isSelected() const { return mIsSelected; }
+ bool isInSelection() const;
void setUnselected() { mIsSelected = FALSE; }
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index efffd0f98e..81eb1d397e 100644
--- 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,193 @@ 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 error(U32 pStatus, const std::string& pReason);
+private:
+ LLSD mMemberData;
+};
+
+void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason)
+{
+ LL_WARNS("GrpMgr") << "Error receiving group member data." << 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
--- 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/llhints.cpp b/indra/newview/llhints.cpp
index e15862e2a4..197408b40e 100644
--- 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/llimfloater.cpp b/indra/newview/llimfloater.cpp
index f67464078b..63eedcdfea 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -56,7 +56,7 @@
#include "llrootview.h"
#include "llspeakers.h"
#include "llviewerchat.h"
-
+#include "llautoreplace.h"
LLIMFloater::LLIMFloater(const LLUUID& session_id)
: LLTransientDockableFloater(NULL, true, session_id),
@@ -255,6 +255,8 @@ BOOL LLIMFloater::postBuild()
mInputEditor->setMaxTextLength(1023);
// enable line history support for instant message bar
mInputEditor->setEnableLineHistory(TRUE);
+ // *TODO Establish LineEditor with autoreplace callback
+ mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
LLFontGL* font = LLViewerChat::getChatFont();
mInputEditor->setFont(font);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b86c453d61..14a228df1c 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -71,6 +71,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
@@ -1355,7 +1358,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
+ // MAINT-1197: This is temp code to work around a deselection/reselection bug. Please discard when merging CHUI.
+ LLFolderViewItem* item_to_select = mRoot->getNextUnselectedItem();
LLFolderView::removeCutItems();
+ mRoot->setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, false);
return;
}
else if ("copy" == action)
@@ -1396,6 +1402,29 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, 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()
@@ -2548,14 +2577,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;
@@ -2743,7 +2781,10 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
else if ("cut" == action)
{
cutToClipboard();
+ // MAINT-1197: This is temp code to work around a deselection/reselection bug. Please discard when merging CHUI.
+ LLFolderViewItem* item_to_select = mRoot->getNextUnselectedItem();
LLFolderView::removeCutItems();
+ mRoot->setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, false);
return;
}
else if ("copy" == action)
@@ -4397,6 +4438,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 +4447,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"));
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index dc9e88d54d..118430efe1 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -197,6 +197,8 @@ 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();
@@ -214,7 +216,6 @@ public:
virtual BOOL isItemCopyable() const;
virtual BOOL hasChildren() const { return FALSE; }
virtual BOOL isUpToDate() const { return TRUE; }
-
/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
LLViewerInventoryItem* getItem() const;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ab5b082915..e98d3f88a6 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -440,7 +440,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 +460,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();
+ }
+}
+
- 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)
+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)
+ {
+ 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");
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 5cf9c528b0..909f7fd10b 100644
--- 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);
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 8092f3bf36..6e23d7c701 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -822,6 +822,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)
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 71dd963f28..05c81957c6 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -966,6 +966,7 @@ void LLInventoryPanel::doToSelected(const LLSD& userdata)
void LLInventoryPanel::doCreate(const LLSD& userdata)
{
+ reset_inventory_filter();
menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
}
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 459e52c4f4..97ba5b634a 100644
--- 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. */
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 025181ead5..8d9d70b50e 100644
--- 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,6 +1208,12 @@ 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();
@@ -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
--- 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/llmachineid.cpp b/indra/newview/llmachineid.cpp
index 778693876e..cd6473921d 100644
--- 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/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index a8da94f75e..c8b446872b 100644
--- 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;
@@ -1871,7 +1894,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/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index f6df4cdfbf..00a0bf8894 100644
--- 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 );
@@ -1251,7 +1263,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 +2072,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/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 3a88fbd96d..362308c176 100644
--- 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
@@ -687,7 +688,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())
@@ -1580,7 +1583,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 +1652,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 +1684,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 +1694,12 @@ 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);
+ gClipProgram.uniform4fv("clip_plane", 1, plane.v);
+
BOOL particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
BOOL clouds = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS);
@@ -1729,6 +1750,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 +2312,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/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 93dd82957f..0b009b68f7 100644
--- 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/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 7650fe9229..99b4707158 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -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);
}
-
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
new file mode 100644
index 0000000000..dd5f1ea689
--- /dev/null
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -0,0 +1,238 @@
+/**
+* @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 (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;
+ }
+
+ llassert(!mIsInitialized);
+ if (mIsInitialized)
+ {
+ quit();
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::initialize()
+{
+ llassert(!mIsInitialized);
+ 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()
+{
+ llassert(mIsInitialized);
+ if (mIsInitialized)
+ {
+ 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 (getMode() == kRebakeNavMesh_RequestSent)
+ {
+ setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default);
+ }
+
+ if (!pResponseStatus)
+ {
+ LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh");
+ }
+}
+
+void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus)
+{
+ llassert(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);
+ 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 100644
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 c899e8991e..92ac435f08 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -361,7 +361,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 +385,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 +427,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 +451,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();
@@ -1097,11 +1121,13 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
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]);
@@ -1620,7 +1646,7 @@ void LLMeshUploadThread::doWholeModelUpload()
mCurlRequest->process();
//sleep for 10ms to prevent eating a whole core
apr_sleep(10000);
- } while (!LLAppViewer::isQuitting() && mCurlRequest->getQueued() > 0);
+ } while (!LLAppViewer::isQuitting() && mPendingUploads > 0);
}
delete mCurlRequest;
@@ -1642,7 +1668,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 +1684,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 +1821,12 @@ void LLMeshLODResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
-
+ // 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)
@@ -1851,6 +1881,12 @@ void LLMeshSkinInfoResponder::completedRaw(U32 status, const std::string& reason
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ // 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)
@@ -1905,6 +1941,11 @@ void LLMeshDecompositionResponder::completedRaw(U32 status, const std::string& r
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
S32 data_size = buffer->countAfter(channels.in(), NULL);
if (status < 200 || status > 400)
@@ -1959,6 +2000,12 @@ void LLMeshPhysicsShapeResponder::completedRaw(U32 status, const std::string& re
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ // 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)
@@ -2013,6 +2060,12 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const LLIOPipe::buffer_ptr_t& buffer)
{
+ // thread could have already be destroyed during logout
+ if( !gMeshRepo.mThread )
+ {
+ return;
+ }
+
if (status < 200 || status > 400)
{
//llwarns
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index da81bb057b..6e301c26a2 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -405,6 +405,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/llmoveview.cpp b/indra/newview/llmoveview.cpp
index c3d8b91d67..93f7146fc8 100644
--- 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);
}
/**
@@ -710,7 +710,7 @@ void LLPanelStandStopFlying::updatePosition()
left_tb_width = toolbar_left->getRect().getWidth();
}
- if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container"))
+ if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"))
{
panel_ssf_container->setOrigin(0, y_pos);
}
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index a7059eb519..54522bb7f6 100644
--- 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)
{
@@ -288,6 +307,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;
}
}
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 4e28d1f526..b0fbad33b0 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -68,7 +68,7 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
{}
// 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 +78,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 +204,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 +228,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 +271,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 +293,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)
@@ -336,7 +329,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
// ...schedule a callback
LLAvatarNameCache::get(id,
boost::bind(&LLNameListCtrl::onAvatarNameCache,
- this, _1, _2));
+ this, _1, _2, item->getHandle()));
}
break;
}
@@ -392,7 +385,8 @@ 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)
{
std::string name;
if (mShortNames)
@@ -400,20 +394,17 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
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();
}
@@ -431,3 +422,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..3ac0565761 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -33,6 +33,36 @@
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>
{
@@ -85,9 +115,9 @@ protected:
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,12 +140,14 @@ public:
void setAllowCallingCardDrop(BOOL b) { mAllowCallingCardDrop = b; }
+ void sortByName(BOOL ascending);
+
/*virtual*/ void updateColumns();
/*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;
@@ -124,24 +156,5 @@ private:
bool mShortNames; // display name only, no SLID
};
-/**
- * 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/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 00ff81724c..f8f0f7d243 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -52,6 +52,7 @@
#include "lltranslate.h"
#include "llresizehandle.h"
+#include "llautoreplace.h"
S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
@@ -89,6 +90,7 @@ BOOL LLNearbyChatBar::postBuild()
{
mChatBox = getChild<LLLineEditor>("chat_box");
+ mChatBox->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7c6287967a..16c51138a9 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -128,6 +128,8 @@ const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
TELEPORT_OFFERED("TeleportOffered"),
+ TELEPORT_OFFERED_MATURITY_EXCEEDED("TeleportOffered_MaturityExceeded"),
+ TELEPORT_OFFERED_MATURITY_BLOCKED("TeleportOffered_MaturityBlocked"),
TELEPORT_OFFER_SENT("TeleportOfferSent"),
IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
@@ -149,6 +151,8 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
|| INVENTORY_DECLINED == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
|| TELEPORT_OFFERED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName()
|| TELEPORT_OFFER_SENT == notification->getName()
|| IM_SYSTEM_MESSAGE_TIP == notification->getName();
}
@@ -169,7 +173,9 @@ bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
+ || TELEPORT_OFFERED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
}
// static
@@ -177,7 +183,9 @@ bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
+ || TELEPORT_OFFERED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
}
// static
@@ -185,7 +193,9 @@ bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification
{
return OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName();
+ || TELEPORT_OFFERED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
}
// static
@@ -212,7 +222,9 @@ bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
if(OFFER_FRIENDSHIP == notification->getName()
|| USER_GIVE_ITEM == notification->getName()
- || TELEPORT_OFFERED == notification->getName())
+ || TELEPORT_OFFERED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
+ || TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName())
{
// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
return ! isIMFloaterOpened(notification);
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index f792f53ac5..3d8150eed3 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -97,6 +97,13 @@ bool LLNotificationManager::onNotification(const LLSD& notify)
{
LLSysHandler* handle = NULL;
+ // Don't bother if we're going down.
+ // Otherwise we might crash when trying to use handlers that are already dead.
+ if( LLApp::isExiting() )
+ {
+ return false;
+ }
+
if (LLNotifications::destroyed())
return false;
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index a64b4ec94d..77e1487f38 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -116,7 +116,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 );
@@ -127,6 +127,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/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 03404e816b..d42056ef9d 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -574,6 +574,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);
}
}
@@ -834,11 +835,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;
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 7301b305b2..202be9671b 100644
--- 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"
@@ -46,6 +47,7 @@
#include "llface.h"
#include "lllineeditor.h"
#include "llmediaentry.h"
+#include "llnotificationsutil.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@@ -104,27 +106,11 @@ 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->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);
}
mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
@@ -504,7 +490,7 @@ void LLPanelFace::getState()
&& 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);
@@ -595,28 +581,6 @@ void LLPanelFace::getState()
}
- 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);
- }
- }
-
-
// planar align
bool align_planar = false;
bool identical_planar_aligned = false;
@@ -1190,3 +1154,35 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
self->sendTextureInfo();
}
+void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
+{
+ LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture 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");
+ }
+ }
+}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index 42be9b257f..3b5a9b1398 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -91,6 +91,15 @@ protected:
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
+private:
+
+ /*
+ * 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);
+
};
#endif
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index b494c7d403..0e6f5b8924 100644
--- 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..993ffb7825 100644
--- 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
@@ -313,11 +315,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 +698,45 @@ 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.
+ 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 +745,43 @@ 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)
+{
+ 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..1b4e8e2645 100644
--- 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);
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 7a15d93181..b9b347d4be 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -83,6 +83,7 @@ public:
LLTextBox *mGroupName;
std::string mOwnerWarning;
std::string mAlreadyInGroup;
+ std::string mTooManySelected;
bool mConfirmedOwnerInvite;
void (*mCloseCallback)(void* data);
@@ -185,6 +186,17 @@ void LLPanelGroupInvite::impl::submitInvitations()
role_member_pairs[item->getUUID()] = role_id;
}
+ const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.
+ 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)
@@ -455,10 +467,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(
+ 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
@@ -467,7 +480,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
}
else
{
- names.push_back(fullname);
+ names.push_back(av_name.getLegacyName());
}
}
}
@@ -475,12 +488,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.getLegacyName());
mImplementation->addUsers(names, agent_ids);
}
@@ -558,8 +571,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 +634,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
--- 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..37755fb851 100644
--- 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";
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index f825ee3215..ff106882f4 100644
--- 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.
@@ -744,7 +745,6 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
mHasMatch(FALSE),
mNumOwnerAdditions(0)
{
- mUdpateSessionID = LLUUID::null;
}
LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
@@ -1426,13 +1426,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 +1554,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 +1581,41 @@ 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;
+ LLNameListCtrl::NameItem item_params;
+ item_params.value = data->getID();
- row["columns"][0]["column"] = "name";
- // value is filled in by name list control
-
- 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;
-
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.getLegacyName()))
{
- addMemberToList(id, data);
+ addMemberToList(member);
if(!mMembersList->getEnabled())
{
mMembersList->setEnabled(TRUE);
@@ -1665,27 +1654,29 @@ 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.getLegacyName()))
{
- 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));
+ LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
+ this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
}
}
@@ -1987,7 +1978,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc)
if (!gdatap || !gdatap->isMemberDataComplete())
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
if (!gdatap || !gdatap->isRoleMemberDataComplete())
@@ -2580,7 +2571,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect()
}
else
{
- LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
if (gdatap->isRoleDataComplete())
@@ -2604,6 +2595,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..bead8bd85b 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -187,8 +187,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,9 +210,6 @@ 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;
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index b3adfac8a2..26cd3ff1c1 100644
--- 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/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 76aadcd913..bcb90bcb56 100644
--- 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"
@@ -104,7 +105,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 +119,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 +139,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)
+ 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));
+
+ // 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++)
{
- LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
- LLStartUp::setStartSLURL(slurl);
+ 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);
+ }
}
- updateLocationCombo(false);
-
- LLComboBox* server_choice_combo = sInstance->getChild<LLComboBox>("server_combo");
- server_choice_combo->setCommitCallback(onSelectServer, NULL);
- server_choice_combo->setFocusLostCallback(boost::bind(onServerComboLostFocus, _1));
- updateServerCombo();
+ 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 +223,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()
@@ -389,25 +428,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 +608,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 +637,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)
+
+ 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 0:
+ case LLSLURL::LOCATION:
+ {
+ std::string slurl_grid = LLGridManager::getInstance()->getGrid(new_start_slurl.getGrid());
+ if ( ! slurl_grid.empty() ) // is that a valid grid?
{
- LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
- break;
- }
- case 1:
- {
- LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
- break;
- }
- default:
- {
- 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 +734,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 +750,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();
- char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0);
- char* curl_version = curl_escape(version.c_str(), 0);
+ // Grid
+ params["grid"] = LLGridManager::getInstance()->getGridId();
- oStr << "&channel=" << curl_channel;
- oStr << "&version=" << curl_version;
+ // add OS info
+ params["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
- curl_free(curl_channel);
- curl_free(curl_version);
+ // sourceid
+ params["sourceid"] = gSavedSettings.getString("sourceid");
+
+ // 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 +813,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 +823,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 +873,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 +912,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,113 +920,99 @@ 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())
+ 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());
+
+ /*
+ * 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)
{
- combo_val = combo->getValue();
+ 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;
}
-
- 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)
+void LLPanelLogin::onLocationSLURL()
{
- if (!sInstance)
- {
- return;
- }
+ LLComboBox* location_combo = getChild<LLComboBox>("start_location_combo");
+ std::string location = location_combo->getValue().asString();
+ LL_DEBUGS("AppInit")<<location<<LL_ENDL;
- LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
- if(fe == combo)
- {
- onSelectServer(combo, NULL);
- }
+ LLStartUp::setStartSLURL(location); // calls onUpdateStartSLURL, above
}
-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);
-}
std::string canonicalize_username(const std::string& name)
{
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index a439c4ff6b..c71cfc3783 100644
--- 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/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index c11597f532..9f3273da2d 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -306,6 +306,7 @@ void LLPanelMainInventory::newWindow()
void LLPanelMainInventory::doCreate(const LLSD& userdata)
{
+ reset_inventory_filter();
menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
}
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 66c9c323cb..5d75375847 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -115,8 +115,8 @@ void LLPanelMarketplaceInbox::onFocusReceived()
if (sidepanel_inventory)
{
sidepanel_inventory->clearSelections(true, false);
- }
-
+ }
+
gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
}
@@ -168,8 +168,8 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
if (inbox_item_view && inbox_item_view->isFresh())
{
fresh_item_count++;
- }
- }
+ }
+ }
}
}
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index c01adc3c35..a50d9074f7 100644
--- 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/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 1f77e7a602..d87b565b32 100644
--- 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 ))
@@ -462,9 +461,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 +500,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 +558,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 +1217,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 +1873,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 +1960,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
--- 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/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 59130236f2..51ab7649a4 100644
--- 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,6 +333,34 @@ 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
@@ -384,7 +425,7 @@ void LLPanelPermissions::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");
@@ -414,7 +455,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 +635,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 +853,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/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 12eea7844d..13b746dbab 100644
--- 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);
@@ -255,7 +258,7 @@ void LLPanelVolume::getState( )
owners_identical = 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 +354,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 +498,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;
@@ -873,10 +876,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
--- 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/llpathfindingcharacter.cpp b/indra/newview/llpathfindingcharacter.cpp
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..2dd01e931e
--- /dev/null
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -0,0 +1,1049 @@
+/**
+* @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 error(U32 pStatus, const std::string& pReason);
+
+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 error(U32 pStatus, const std::string& pReason);
+
+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 error(U32 pStatus, const std::string& pReason);
+
+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 error(U32 pStatus, const std::string& pReason);
+
+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 std::string &pURL);
+ void handleTerrainLinksetsResult(const LLSD &pContent);
+ void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, 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 error(U32 pStatus, const std::string &pReason);
+
+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 error(U32 pStatus, const std::string &pReason);
+
+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 error(U32 pStatus, const std::string &pReason);
+
+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::error(U32 pStatus, const std::string& pReason)
+{
+ llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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::error(U32 pStatus, const std::string& pReason)
+{
+ mNavMeshPtr->handleNavMeshError(pStatus, pReason, 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::error(U32 pStatus, const std::string &pReason)
+{
+ llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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::error(U32 pStatus, const std::string &pReason)
+{
+ llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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 std::string &pURL)
+{
+ llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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 std::string &pURL)
+{
+ 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::error(U32 pStatus, const std::string &pReason)
+{
+ mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, 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::error(U32 pStatus, const std::string &pReason)
+{
+ mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, 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::error(U32 pStatus, const std::string &pReason)
+{
+ llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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 100644
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 100644
index 0000000000..e01dd3a152
--- /dev/null
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -0,0 +1,205 @@
+/**
+* @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 std::string &pURL, U32 pNavMeshVersion)
+{
+ llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << 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 100644
index 0000000000..7a844f54ce
--- /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 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 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..858d3203c0
--- /dev/null
+++ b/indra/newview/llpathfindingobject.cpp
@@ -0,0 +1,199 @@
+/**
+* @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)
+ {
+ 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 100644
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 100644
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 100644
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 100644
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 100644
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/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index e124916c48..cb6989c9dd 100644
--- 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,16 +129,43 @@ 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());
- }
+ mParamCache[param] = mCharacter->getVisualParam(param_name.c_str());
+ }
+
+ if (mParamCache[param])
+ {
+ return mParamCache[param]->getWeight();
+ }
+ else
+ {
+ return sDefaultController[controller_key[param]];
+ }
+ }
+
+
void setParamValue(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;
};
@@ -427,7 +474,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 +517,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;
diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp
index 450f9b2be7..9902d047e4 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/newview/llpolymesh.cpp
@@ -129,22 +129,22 @@ void LLPolyMeshSharedData::freeMeshData()
{
mNumVertices = 0;
- delete [] mBaseCoords;
+ ll_aligned_free_16(mBaseCoords);
mBaseCoords = NULL;
- delete [] mBaseNormals;
+ ll_aligned_free_16(mBaseNormals);
mBaseNormals = NULL;
- delete [] mBaseBinormals;
+ ll_aligned_free_16(mBaseBinormals);
mBaseBinormals = NULL;
- delete [] mTexCoords;
+ ll_aligned_free_16(mTexCoords);
mTexCoords = NULL;
- delete [] mDetailTexCoords;
+ ll_aligned_free_16(mDetailTexCoords);
mDetailTexCoords = NULL;
- delete [] mWeights;
+ ll_aligned_free_16(mWeights);
mWeights = NULL;
}
@@ -229,15 +229,19 @@ U32 LLPolyMeshSharedData::getNumKB()
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 ];
+ 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++)
{
- mWeights[i] = 0.f;
+ mBaseCoords[i].clear();
+ mBaseNormals[i].clear();
+ mBaseBinormals[i].clear();
+ mTexCoords[i].clear();
+ mWeights[i] = 0.f;
}
mNumVertices = numVertices;
return TRUE;
@@ -408,39 +412,47 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName )
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;
- }
-
+ 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
@@ -767,21 +779,28 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
{
// 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);
+ 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);
- 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;
+ 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();
}
}
@@ -906,7 +925,7 @@ void LLPolyMesh::dumpDiagInfo()
//-----------------------------------------------------------------------------
// getWritableCoords()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableCoords()
+LLVector4a *LLPolyMesh::getWritableCoords()
{
return mCoords;
}
@@ -914,7 +933,7 @@ LLVector4 *LLPolyMesh::getWritableCoords()
//-----------------------------------------------------------------------------
// getWritableNormals()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableNormals()
+LLVector4a *LLPolyMesh::getWritableNormals()
{
return mNormals;
}
@@ -922,7 +941,7 @@ LLVector4 *LLPolyMesh::getWritableNormals()
//-----------------------------------------------------------------------------
// getWritableBinormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getWritableBinormals()
+LLVector4a *LLPolyMesh::getWritableBinormals()
{
return mBinormals;
}
@@ -931,7 +950,7 @@ LLVector3 *LLPolyMesh::getWritableBinormals()
//-----------------------------------------------------------------------------
// getWritableClothingWeights()
//-----------------------------------------------------------------------------
-LLVector4 *LLPolyMesh::getWritableClothingWeights()
+LLVector4a *LLPolyMesh::getWritableClothingWeights()
{
return mClothingWeights;
}
@@ -947,7 +966,7 @@ LLVector2 *LLPolyMesh::getWritableTexCoords()
//-----------------------------------------------------------------------------
// getScaledNormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledNormals()
+LLVector4a *LLPolyMesh::getScaledNormals()
{
return mScaledNormals;
}
@@ -955,7 +974,7 @@ LLVector3 *LLPolyMesh::getScaledNormals()
//-----------------------------------------------------------------------------
// getScaledBinormals()
//-----------------------------------------------------------------------------
-LLVector3 *LLPolyMesh::getScaledBinormals()
+LLVector4a *LLPolyMesh::getScaledBinormals()
{
return mScaledBinormals;
}
@@ -966,17 +985,17 @@ LLVector3 *LLPolyMesh::getScaledBinormals()
//-----------------------------------------------------------------------------
void LLPolyMesh::initializeForMorph()
{
- for (U32 i = 0; i < mSharedData->mNumVertices; ++i)
+ 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)
{
- mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
- mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
+ mClothingWeights[i].clear();
}
-
- 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);
}
//-----------------------------------------------------------------------------
@@ -1098,7 +1117,7 @@ BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
{
mAvatar = avatarp;
- mDefaultVec.setVec(0.001f, 0.001f, 0.001f);
+ mDefaultVec.splat(0.001f);
}
//-----------------------------------------------------------------------------
@@ -1171,8 +1190,12 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
//-----------------------------------------------------------------------------
// 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;
@@ -1228,11 +1251,14 @@ LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
{
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] = direction;
- cloned_morph_data->mNormals[v] = LLVector3(0,0,0);
- cloned_morph_data->mBinormals[v] = LLVector3(0,0,0);
+ cloned_morph_data->mCoords[v] = dir;
+ cloned_morph_data->mNormals[v].clear();
+ cloned_morph_data->mBinormals[v].clear();
}
return cloned_morph_data;
}
@@ -1243,17 +1269,27 @@ LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
{
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++)
{
- 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;
- }
+ 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;
}
diff --git a/indra/newview/llpolymesh.h b/indra/newview/llpolymesh.h
index ba2bf85570..850171d169 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/newview/llpolymesh.h
@@ -73,9 +73,9 @@ private:
// vertex data
S32 mNumVertices;
- LLVector3 *mBaseCoords;
- LLVector3 *mBaseNormals;
- LLVector3 *mBaseBinormals;
+ LLVector4a *mBaseCoords;
+ LLVector4a *mBaseNormals;
+ LLVector4a *mBaseBinormals;
LLVector2 *mTexCoords;
LLVector2 *mDetailTexCoords;
F32 *mWeights;
@@ -217,41 +217,41 @@ public:
}
// Get coords
- const LLVector4 *getCoords() const{
+ const LLVector4a *getCoords() const{
return mCoords;
}
// non const version
- LLVector4 *getWritableCoords();
+ LLVector4a *getWritableCoords();
// Get normals
- const LLVector4 *getNormals() const{
+ const LLVector4a *getNormals() const{
return mNormals;
}
// Get normals
- const LLVector3 *getBinormals() const{
+ const LLVector4a *getBinormals() const{
return mBinormals;
}
// Get base mesh normals
- const LLVector3 *getBaseNormals() const{
+ const LLVector4a *getBaseNormals() const{
llassert(mSharedData);
return mSharedData->mBaseNormals;
}
// Get base mesh normals
- const LLVector3 *getBaseBinormals() const{
+ const LLVector4a *getBaseBinormals() const{
llassert(mSharedData);
return mSharedData->mBaseBinormals;
}
// intermediate morphed normals and output normals
- LLVector4 *getWritableNormals();
- LLVector3 *getScaledNormals();
+ LLVector4a *getWritableNormals();
+ LLVector4a *getScaledNormals();
- LLVector3 *getWritableBinormals();
- LLVector3 *getScaledBinormals();
+ LLVector4a *getWritableBinormals();
+ LLVector4a *getScaledBinormals();
// Get texCoords
const LLVector2 *getTexCoords() const {
@@ -275,9 +275,9 @@ public:
F32 *getWritableWeights() const;
- LLVector4 *getWritableClothingWeights();
+ LLVector4a *getWritableClothingWeights();
- const LLVector4 *getClothingWeights()
+ const LLVector4a *getClothingWeights()
{
return mClothingWeights;
}
@@ -341,17 +341,17 @@ protected:
// Single array of floats for allocation / deletion
F32 *mVertexData;
// deformed vertices (resulting from application of morph targets)
- LLVector4 *mCoords;
+ LLVector4a *mCoords;
// deformed normals (resulting from application of morph targets)
- LLVector3 *mScaledNormals;
+ LLVector4a *mScaledNormals;
// output normals (after normalization)
- LLVector4 *mNormals;
+ LLVector4a *mNormals;
// deformed binormals (resulting from application of morph targets)
- LLVector3 *mScaledBinormals;
+ LLVector4a *mScaledBinormals;
// output binormals (after normalization)
- LLVector3 *mBinormals;
+ LLVector4a *mBinormals;
// weight values that mark verts as clothing/skin
- LLVector4 *mClothingWeights;
+ LLVector4a *mClothingWeights;
// output texture coordinates
LLVector2 *mTexCoords;
@@ -406,6 +406,16 @@ public:
LLPolySkeletalDistortion(LLVOAvatar *avatarp);
~LLPolySkeletalDistortion();
+ 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
LLPolySkeletalDistortionInfo* getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
// This sets mInfo and calls initialization functions
@@ -419,17 +429,17 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 0.1f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mDefaultVec; }
+ /*virtual*/ const LLVector4a& 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;};
+ /*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:
typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
joint_vec_map_t mJointScales;
joint_vec_map_t mJointOffsets;
- LLVector3 mDefaultVec;
+ LLVector4a mDefaultVec;
// Backlink only; don't make this an LLPointer.
LLVOAvatar *mAvatar;
};
diff --git a/indra/newview/llpolymorph.cpp b/indra/newview/llpolymorph.cpp
index cefd7df3fe..bd96608641 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/newview/llpolymorph.cpp
@@ -48,7 +48,7 @@ LLPolyMorphData::LLPolyMorphData(const std::string& morph_name)
mNumIndices = 0;
mCurrentIndex = 0;
mTotalDistortion = 0.f;
- mAvgDistortion.zeroVec();
+ mAvgDistortion.clear();
mMaxDistortion = 0.f;
mVertexIndices = NULL;
mCoords = NULL;
@@ -73,9 +73,9 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
{
const S32 numVertices = mNumIndices;
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
+ mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
+ mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
+ mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
mTexCoords = new LLVector2[numVertices];
mVertexIndices = new U32[numVertices];
@@ -89,17 +89,12 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) :
}
}
-
//-----------------------------------------------------------------------------
// ~LLPolyMorphData()
//-----------------------------------------------------------------------------
LLPolyMorphData::~LLPolyMorphData()
{
- delete [] mVertexIndices;
- delete [] mCoords;
- delete [] mNormals;
- delete [] mBinormals;
- delete [] mTexCoords;
+ freeData();
}
//-----------------------------------------------------------------------------
@@ -119,18 +114,23 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
}
//-------------------------------------------------------------------------
+ // free any existing data
+ //-------------------------------------------------------------------------
+ freeData();
+
+ //-------------------------------------------------------------------------
// allocate vertices
//-------------------------------------------------------------------------
- mCoords = new LLVector3[numVertices];
- mNormals = new LLVector3[numVertices];
- mBinormals = new LLVector3[numVertices];
+ mCoords = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
+ mNormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
+ mBinormals = static_cast<LLVector4a*>(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a)));
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();
+ mAvgDistortion.clear();
mMesh = mesh;
//-------------------------------------------------------------------------
@@ -152,36 +152,36 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
}
- numRead = fread(&mCoords[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mCoords[v].mV, sizeof(F32), 3);
+ 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].magVec();
+ F32 magnitude = mCoords[v].getLength3().getF32();
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]);
+ LLVector4a t;
+ t.setAbs(mCoords[v]);
+ mAvgDistortion.add(t);
if (magnitude > mMaxDistortion)
{
mMaxDistortion = magnitude;
}
- numRead = fread(&mNormals[v].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mNormals[v].mV, sizeof(F32), 3);
+ 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].mV, sizeof(F32), 3, fp);
- llendianswizzle(&mBinormals[v].mV, sizeof(F32), 3);
+ 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;
@@ -200,13 +200,49 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh)
mNumIndices++;
}
- mAvgDistortion = mAvgDistortion * (1.f/(F32)mNumIndices);
- mAvgDistortion.normVec();
+ 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()
@@ -367,9 +403,9 @@ BOOL LLPolyMorphTarget::parseData(LLXmlTreeNode* node)
//-----------------------------------------------------------------------------
// getVertexDistortion()
//-----------------------------------------------------------------------------
-LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
+LLVector4a LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh *mesh)
{
- if (!mMorphData || mMesh != mesh) return LLVector3::zero;
+ if (!mMorphData || mMesh != mesh) return LLVector4a::getZero();
for(U32 index = 0; index < mMorphData->mNumIndices; index++)
{
@@ -379,17 +415,17 @@ LLVector3 LLPolyMorphTarget::getVertexDistortion(S32 requested_index, LLPolyMesh
}
}
- return LLVector3::zero;
+ return LLVector4a::getZero();
}
//-----------------------------------------------------------------------------
// getFirstDistortion()
//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
- if (!mMorphData) return &LLVector3::zero;
+ if (!mMorphData) return &LLVector4a::getZero();
- LLVector3* resultVec;
+ LLVector4a* resultVec;
mMorphData->mCurrentIndex = 0;
if (mMorphData->mNumIndices)
{
@@ -411,11 +447,11 @@ const LLVector3 *LLPolyMorphTarget::getFirstDistortion(U32 *index, LLPolyMesh **
//-----------------------------------------------------------------------------
// getNextDistortion()
//-----------------------------------------------------------------------------
-const LLVector3 *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
+const LLVector4a *LLPolyMorphTarget::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
{
- if (!mMorphData) return &LLVector3::zero;
+ if (!mMorphData) return &LLVector4a::getZero();
- LLVector3* resultVec;
+ LLVector4a* resultVec;
mMorphData->mCurrentIndex++;
if (mMorphData->mCurrentIndex < mMorphData->mNumIndices)
{
@@ -451,7 +487,7 @@ F32 LLPolyMorphTarget::getTotalDistortion()
//-----------------------------------------------------------------------------
// getAvgDistortion()
//-----------------------------------------------------------------------------
-const LLVector3& LLPolyMorphTarget::getAvgDistortion()
+const LLVector4a& LLPolyMorphTarget::getAvgDistortion()
{
if (mMorphData)
{
@@ -459,7 +495,7 @@ const LLVector3& LLPolyMorphTarget::getAvgDistortion()
}
else
{
- return LLVector3::zero;
+ return LLVector4a::getZero();
}
}
@@ -481,6 +517,8 @@ F32 LLPolyMorphTarget::getMaxDistortion()
//-----------------------------------------------------------------------------
// apply()
//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_APPLY_MORPH_TARGET("Apply Morph");
+
void LLPolyMorphTarget::apply( ESex avatar_sex )
{
if (!mMorphData || mNumMorphMasksPending > 0)
@@ -488,6 +526,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
return;
}
+ LLFastTimer t(FTM_APPLY_MORPH_TARGET);
+
mLastSex = avatar_sex;
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.
@@ -508,15 +548,15 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
if (delta_weight != 0.f)
{
llassert(!mMesh->isLOD());
- LLVector4 *coords = mMesh->getWritableCoords();
+ LLVector4a *coords = mMesh->getWritableCoords();
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector4 *normals = mMesh->getWritableNormals();
+ LLVector4a *scaled_normals = mMesh->getScaledNormals();
+ LLVector4a *normals = mMesh->getWritableNormals();
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
- LLVector3 *binormals = mMesh->getWritableBinormals();
+ LLVector4a *scaled_binormals = mMesh->getScaledBinormals();
+ LLVector4a *binormals = mMesh->getWritableBinormals();
- LLVector4 *clothing_weights = mMesh->getWritableClothingWeights();
+ LLVector4a *clothing_weights = mMesh->getWritableClothingWeights();
LLVector2 *tex_coords = mMesh->getWritableTexCoords();
F32 *maskWeightArray = (mVertMask) ? mVertMask->getMorphMaskWeights() : NULL;
@@ -531,31 +571,38 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
maskWeight = maskWeightArray[vert_index_morph];
}
- coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight);
+
+ LLVector4a pos = mMorphData->mCoords[vert_index_morph];
+ pos.mul(delta_weight*maskWeight);
+ coords[vert_index_mesh].add(pos);
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;
+ 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
- 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);
+ 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];
+ norm.normalize3fast();
+ normals[vert_index_mesh] = norm;
// 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;
-
+ LLVector4a binorm = mMorphData->mBinormals[vert_index_morph];
+ 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;
}
@@ -582,7 +629,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
//-----------------------------------------------------------------------------
void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert)
{
- LLVector4 *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
+ LLVector4a *clothing_weights = getInfo()->mIsClothingMorph ? mMesh->getWritableClothingWeights() : NULL;
if (!mVertMask)
{
@@ -596,29 +643,47 @@ void LLPolyMorphTarget::applyMask(U8 *maskTextureData, S32 width, S32 height, S3
if (maskWeights)
{
- LLVector4 *coords = mMesh->getWritableCoords();
- LLVector3 *scaled_normals = mMesh->getScaledNormals();
- LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
+ 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
- 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;
+ 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)
{
- 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];
+ 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);
}
}
}
@@ -654,7 +719,7 @@ LLPolyVertexMask::~LLPolyVertexMask()
//-----------------------------------------------------------------------------
// generateMask()
//-----------------------------------------------------------------------------
-void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights)
+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;
@@ -698,7 +763,7 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height,
if (clothing_weights)
{
- clothing_weights[vertIndex].mV[VW] = mWeights[index];
+ clothing_weights[vertIndex].getF32ptr()[VW] = mWeights[index];
}
}
mWeightsGenerated = TRUE;
diff --git a/indra/newview/llpolymorph.h b/indra/newview/llpolymorph.h
index 8a024f2e9e..678599d7e1 100644
--- a/indra/newview/llpolymorph.h
+++ b/indra/newview/llpolymorph.h
@@ -48,6 +48,16 @@ public:
~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; }
@@ -58,15 +68,18 @@ public:
U32 mNumIndices;
U32* mVertexIndices;
U32 mCurrentIndex;
- LLVector3* mCoords;
- LLVector3* mNormals;
- LLVector3* mBinormals;
+ 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
- LLVector3 mAvgDistortion; // average vertex distortion, to infer directionality of the morph
+ LLVector4a mAvgDistortion; // average vertex distortion, to infer directionality of the morph
LLPolyMeshSharedData* mMesh;
+
+private:
+ void freeData();
};
//-----------------------------------------------------------------------------
@@ -78,7 +91,7 @@ public:
LLPolyVertexMask(LLPolyMorphData* morph_data);
~LLPolyVertexMask();
- void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4 *clothing_weights);
+ void generateMask(U8 *maskData, S32 width, S32 height, S32 num_components, BOOL invert, LLVector4a *clothing_weights);
F32* getMorphMaskWeights();
@@ -157,11 +170,11 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion();
- /*virtual*/ const LLVector3& getAvgDistortion();
+ /*virtual*/ const LLVector4a& 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);
+ /*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++; }
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 18626e3273..04934b13f1 100644
--- 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/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 88727bf59b..9c25e69db0 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -815,7 +815,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/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d340b304ca..d2280ea089 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -571,9 +571,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 +605,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 +628,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 +636,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 +660,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)
@@ -714,9 +720,13 @@ void LLScreenChannel::showToastsTop()
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)
@@ -744,7 +754,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 +777,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 +785,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 +809,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/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index eec2c0a521..c3c37141ed 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -276,7 +276,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 +390,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 +593,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 +644,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 +659,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 +684,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())
@@ -955,7 +965,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;
@@ -1387,7 +1397,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 +1518,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()
//-----------------------------------------------------------------------------
@@ -1559,8 +1612,18 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
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
{
@@ -2286,50 +2349,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)
@@ -2543,6 +2562,340 @@ BOOL LLSelectMgr::selectGetRootsModify()
//-----------------------------------------------------------------------------
+// selectGetNonPermanentEnforced() - return TRUE if all objects are not
+// permanent enforced
+//-----------------------------------------------------------------------------
+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++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->isPermanentEnforced())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetPermanent() - return TRUE if all objects are permanent
+//-----------------------------------------------------------------------------
+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++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetCharacter() - return TRUE if all objects are character
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetCharacter()
+{
+ 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->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// 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 )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetNonPathfinding() - return TRUE if all objects are not pathfinding
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetNonPathfinding()
+{
+ 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() || object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ 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++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent() || object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetNonPermanent() - return TRUE if all objects are not permanent
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetNonPermanent()
+{
+ 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;
+}
+
+//-----------------------------------------------------------------------------
+// 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 )
+ {
+ return FALSE;
+ }
+ if( object->flagObjectPermanent())
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// selectGetNonCharacter() - return TRUE if all objects are not character
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetNonCharacter()
+{
+ 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->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// 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++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !node->mValid )
+ {
+ return FALSE;
+ }
+ if( object->flagCharacter())
+ {
+ return FALSE;
+ }
+ }
+
+ 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()))
+ {
+ return FALSE;
+ }
+ }
+ 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++ )
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = node->getObject();
+ if( !object || !node->mValid )
+ {
+ return FALSE;
+ }
+ if( !object->flagCharacter() ||
+ (object->getRegion() != gAgent.getRegion()))
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
// selectGetRootsTransfer() - return TRUE if current agent can transfer all
// selected root objects.
//-----------------------------------------------------------------------------
@@ -4121,8 +4474,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);
}
@@ -4148,12 +4500,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()
//----------------------------------------------------------------------
@@ -5583,7 +5929,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);
}
}
@@ -5610,7 +5956,7 @@ void LLSelectNode::renderOneWireframe(const LLColor4& color)
if (shader)
{
- gHighlightProgram.bind();
+ gDebugProgram.bind();
}
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -5983,8 +6329,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++)
{
@@ -6002,11 +6346,6 @@ void LLSelectMgr::updateSelectionCenter()
}
bbox.addBBoxAgent( object->getBoundingBoxAgent() );
-
- if (object->isJointChild())
- {
- jointed_objects.push_back(object);
- }
}
LLVector3 bbox_center_agent = bbox.getCenterAgent();
@@ -6245,7 +6584,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;
@@ -6296,19 +6635,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() :
@@ -6937,7 +7276,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);
@@ -6975,9 +7314,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() )
{
@@ -7017,7 +7357,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);
@@ -7086,7 +7426,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..ecbb20df1b 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -307,6 +307,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:
@@ -501,7 +510,6 @@ public:
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
@@ -539,8 +547,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 +569,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();
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index 1ce05da849..92c2863ffd 100644
--- 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/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 64b82aa0bb..c351b1a128 100644
--- 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
@@ -146,6 +149,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 +246,9 @@ void LLSidepanelTaskInfo::disableAll()
mDAComboClickAction->clear();
}
+ mDAPathfindingAttributes->setEnabled(FALSE);
+ mDAPathfindingAttributes->setValue(LLStringUtil::null);
+
mDAB->setVisible(FALSE);
mDAO->setVisible(FALSE);
mDAG->setVisible(FALSE);
@@ -301,6 +308,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 +317,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,6 +336,34 @@ 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
@@ -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())
{
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index be0fee2127..124229af06 100644
--- 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
{
@@ -150,6 +151,7 @@ private:
LLUICtrl* mDAEditCost;
LLView* mDALabelClickAction;
LLComboBox* mDAComboClickAction;
+ LLTextBase* mDAPathfindingAttributes;
LLView* mDAB;
LLView* mDAO;
LLView* mDAG;
diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp
index a853726dea..3a82233320 100644
--- 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
--- 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/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 8e62b79d7f..2083afdcf5 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -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,32 @@ static F32 sCurMaxTexPriority = 1.f;
class LLOcclusionQueryPool : public LLGLNamePool
{
+public:
+ LLOcclusionQueryPool()
+ {
+ mCurQuery = 1;
+ }
+
protected:
+
+ std::list<GLuint> mAvailableName;
+ GLuint mCurQuery;
+
virtual GLuint allocateName()
{
- GLuint name;
- glGenQueriesARB(1, &name);
- return name;
+ GLuint ret = 0;
+
+ if (!mAvailableName.empty())
+ {
+ ret = mAvailableName.front();
+ mAvailableName.pop_front();
+ }
+ else
+ {
+ ret = mCurQuery++;
+ }
+
+ return ret;
}
virtual void releaseName(GLuint name)
@@ -98,7 +119,8 @@ protected:
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
LLSpatialGroup::sPendingQueries.erase(name);
#endif
- glDeleteQueriesARB(1, &name);
+ llassert(std::find(mAvailableName.begin(), mAvailableName.end(), name) == mAvailableName.end());
+ mAvailableName.push_back(name);
}
};
@@ -259,79 +281,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,8 +376,6 @@ LLSpatialGroup::~LLSpatialGroup()
}
}
- mOcclusionVerts = NULL;
-
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
clearDrawMap();
clearAtlasList() ;
@@ -550,6 +530,7 @@ void LLSpatialGroup::setVisible()
void LLSpatialGroup::validate()
{
+ ll_assert_aligned(this,64);
#if LL_OCTREE_PARANOIA_CHECK
sg_assert(!isState(DIRTY));
@@ -562,7 +543,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);
@@ -687,6 +668,11 @@ void LLSpatialGroup::rebuildGeom()
if (!isDead())
{
mSpatialPartition->rebuildGeom(this);
+
+ if (isState(LLSpatialGroup::MESH_DIRTY))
+ {
+ gPipeline.markMeshDirty(this);
+ }
}
}
@@ -699,6 +685,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 +709,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 +760,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 +777,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();
@@ -927,16 +925,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
@@ -1204,6 +1200,8 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mCurUpdatingSlotp(NULL),
mCurUpdatingTexture (NULL)
{
+ ll_assert_aligned(this,16);
+
sNodeCount++;
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -1235,8 +1233,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mVisible[i] = 0;
}
- mOcclusionVerts = NULL;
-
mRadius = 1;
mPixelArea = 1024.f;
}
@@ -1249,13 +1245,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();
@@ -1406,7 +1407,7 @@ 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)
@@ -1465,10 +1466,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;
@@ -1476,24 +1481,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();
+ }
}
}
}
@@ -1556,15 +1566,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()
{
@@ -1584,7 +1592,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");
+
+ 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);
@@ -1635,7 +1645,9 @@ void LLSpatialGroup::checkOcclusion()
else
{
assert_states_valid(this);
+
setOcclusionState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF);
+
assert_states_valid(this);
}
@@ -1690,12 +1702,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.
@@ -1726,10 +1732,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)
{
@@ -1738,12 +1747,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
@@ -1751,12 +1760,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]));
}
}
@@ -1841,12 +1850,16 @@ 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);
@@ -2117,7 +2130,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)
{
@@ -2184,7 +2197,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;
@@ -2308,7 +2321,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)
@@ -2480,18 +2493,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);
+ }
}
}
@@ -2615,7 +2631,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())
@@ -2628,7 +2644,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)
{
@@ -2661,7 +2677,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);
@@ -2729,7 +2745,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
- !group->getData().empty();
+ !group->isEmpty();
if (render_objects)
{
@@ -2757,19 +2773,6 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
}
- /*else if (camera && group->mOcclusionVerts.notNull())
- {
- 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);
- }*/
}
}
@@ -2999,15 +3002,17 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
+ if (facep)
+ {
+ ext = facep->mExtents;
- 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
@@ -3471,7 +3476,7 @@ 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();
@@ -3495,24 +3500,30 @@ void renderPhysicsShapes(LLSpatialGroup* group)
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)
{
LLFace* face = drawable->getFace(i);
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff)
+ if (face)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ 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();
}
}
}
@@ -3534,6 +3545,7 @@ void renderTexturePriority(LLDrawable* drawable)
//LLViewerTexture* imagep = facep->getTexture();
//if (imagep)
+ if (facep)
{
//F32 vsize = imagep->mMaxVirtualSize;
@@ -3586,7 +3598,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();
}
@@ -3767,7 +3783,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();
@@ -3808,7 +3828,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());
@@ -3844,8 +3864,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;
@@ -4082,7 +4102,7 @@ public:
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES))
{
- if (!group->getData().empty())
+ if (!group->isEmpty())
{
gGL.diffuseColor3f(0,0,1);
drawBoxOutline(group->mObjectBounds[0],
@@ -4090,7 +4110,7 @@ public:
}
}
- 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;
@@ -4169,18 +4189,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)
- {
- llerrs << "Face texture index out of bounds." << llendl;
- }
- else if (facep->mDrawInfo->mTextureList[index] != facep->getTexture())
+ if (index < 255)
{
- 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;
+ }
}
}
}
@@ -4276,7 +4299,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;
@@ -4500,7 +4523,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);
}
@@ -4686,28 +4709,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++)
@@ -4717,176 +4782,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 1a93145cc5..b1706d9d35 100644
--- 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_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
LLDrawInfo(const LLDrawInfo& rhs)
{
@@ -106,7 +116,7 @@ public:
F32 mPartSize;
F32 mVSize;
LLSpatialGroup* mGroup;
- LLFace* mFace; //associated face
+ LL_ALIGN_16(LLFace* mFace); //associated face
F32 mDistance;
U32 mDrawMode;
@@ -181,7 +191,7 @@ public:
};
};
-LL_ALIGN_PREFIX(64)
+LL_ALIGN_PREFIX(16)
class LLSpatialGroup : public LLOctreeListener<LLDrawable>
{
friend class LLSpatialPartition;
@@ -193,6 +203,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 +283,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 +332,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 +345,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 +397,12 @@ 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()
@@ -415,7 +440,6 @@ public:
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
- LLPointer<LLVertexBuffer> mOcclusionVerts;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
@@ -550,29 +574,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);
@@ -592,28 +621,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];
+
};
@@ -657,6 +699,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);
@@ -671,10 +714,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)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 6b0fc26db7..3d1fd74ba6 100644..100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -186,6 +186,7 @@
#include "llappearancemgr.h"
#include "llavatariconctrl.h"
#include "llvoicechannel.h"
+#include "llpathfindingmanager.h"
#include "lllogin.h"
#include "llevents.h"
@@ -361,6 +362,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);
@@ -720,12 +730,14 @@ 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();
}
@@ -738,8 +750,10 @@ bool idle_startup()
// 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();
@@ -747,11 +761,13 @@ 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();
@@ -768,17 +784,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 );
}
@@ -995,7 +1022,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");
@@ -1159,7 +1186,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
@@ -1922,7 +1948,8 @@ 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")) ||
((start_slurl.getType() == LLSLURL::HOME_LOCATION) && (gAgentStartLocation == "home")))
@@ -2166,6 +2193,9 @@ bool idle_startup()
LLIMFloater::initIMFloater();
display_startup();
+ llassert(LLPathfindingManager::getInstance() != NULL);
+ LLPathfindingManager::getInstance()->initSystem();
+
return TRUE;
}
@@ -2181,21 +2211,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.
@@ -2274,7 +2296,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
// break;
case 2: // Teleport
// Restart the login process, starting at our home locaton
- LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
break;
default:
@@ -2707,9 +2729,10 @@ void LLStartUp::setStartupState( EStartupState state )
getStartupStateString() << " to " <<
startupStateToString(state) << LL_ENDL;
- sPhases->stopPhase(getStartupStateString());
+ getPhases().stopPhase(getStartupStateString());
gStartupState = state;
- sPhases->startPhase(getStartupStateString());
+ getPhases().startPhase(getStartupStateString());
+
postStartupState();
}
@@ -2826,25 +2849,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.
@@ -3215,17 +3246,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())
@@ -3287,11 +3307,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())
{
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 3754aaf966..760e38890b 100644..100755
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -111,7 +111,7 @@ 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
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 89240c982f..ff69c6e9fd 100644
--- 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/llsurface.cpp b/indra/newview/llsurface.cpp
index 66df7dae3e..f64a72a616 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -56,6 +56,7 @@
#include "lldrawable.h"
extern LLPipeline gPipeline;
+extern bool gShiftFrame;
LLColor4U MAX_WATER_COLOR(0, 48, 96, 240);
@@ -294,7 +295,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 +347,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 +622,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;
diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h
index a4ef4fe2de..8052fb0d18 100644
--- 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
diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp
index 5077c2c7e1..a9ba2bce9c 100644
--- 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/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 0cb6c85012..2002647fef 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -242,7 +242,7 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
{
- buildFromFile( "panel_activeim_row.xml", NULL);
+ buildFromFile( "panel_activeim_row.xml");
// Choose which of the pre-created chiclets (IM/group) to use.
// The other one gets hidden.
@@ -356,7 +356,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);
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 467115c928..ad09af6594 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -510,7 +510,13 @@ void LLTexLayerSetBuffer::doUpload()
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);
+
+ //data buffer MUST be allocated using LLImageBase
+ 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'
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
index 74c22b0cdf..fffe20208f 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/newview/lltexlayerparams.h
@@ -67,6 +67,16 @@ public:
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable = NULL) const;
+ void* operator new(size_t size)
+ {
+ return ll_aligned_malloc_16(size);
+ }
+
+ void operator delete(void* ptr)
+ {
+ ll_aligned_free_16(ptr);
+ }
+
// LLVisualParam Virtual functions
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
/*virtual*/ void apply( ESex avatar_sex ) {}
@@ -76,11 +86,11 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ const LLVector4a& 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;};
+ /*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 );
@@ -94,7 +104,7 @@ private:
LLPointer<LLImageRaw> mStaticImageRaw;
BOOL mNeedsCreateTexture;
BOOL mStaticImageInvalid;
- LLVector3 mAvgDistortionVec;
+ LLVector4a mAvgDistortionVec;
F32 mCachedEffectiveWeight;
public:
@@ -143,6 +153,16 @@ public:
LLTexLayerParamColor( LLVOAvatar* avatar );
/* virtual */ ~LLTexLayerParamColor();
+ 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
@@ -155,18 +175,18 @@ public:
// LLViewerVisualParam Virtual functions
/*virtual*/ F32 getTotalDistortion() { return 1.f; }
- /*virtual*/ const LLVector3& getAvgDistortion() { return mAvgDistortionVec; }
+ /*virtual*/ const LLVector4a& 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;};
+ /*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:
- LLVector3 mAvgDistortionVec;
+ LLVector4a mAvgDistortionVec;
};
class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
diff --git a/indra/newview/lltextureatlas.cpp b/indra/newview/lltextureatlas.cpp
index d2e4b01732..f8c1bca8ae 100644
--- a/indra/newview/lltextureatlas.cpp
+++ b/indra/newview/lltextureatlas.cpp
@@ -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/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 8632890bbb..305f6fca0f 100644
--- 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,11 @@ bool LLTextureCacheRemoteWorker::doWrite()
if(idx < 0)
{
idx = mCache->setHeaderCacheEntry(mID, entry, mImageSize, mDataSize); // create the new entry.
+ if(idx >= 0)
+ {
+ //write to the fast cache.
+ llassert_always(mCache->writeToFastCache(idx, mRawImage, mRawDiscardLevel));
+ }
}
else
{
@@ -658,6 +670,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
// Nothing else to do at that point...
done = true;
}
+ mRawImage = NULL;
// Clean up and exit
return done;
@@ -744,10 +757,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 +772,9 @@ LLTextureCache::~LLTextureCache()
{
clearDeleteList() ;
writeUpdatedEntries() ;
+ delete mFastCachep;
+ delete mFastCachePoolp;
+ FREE_MEM(LLImageBase::getPrivatePool(), mFastCachePadBuffer);
}
//////////////////////////////////////////////////////////////////////////////
@@ -879,15 +899,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 +916,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 +959,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 +1002,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 +1773,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 +1811,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 +1830,174 @@ 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
+ 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
+ {
+ LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents());
+ newraw->scale(w, h) ;
+ raw = newraw;
+
+ 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));
+ if(w * h * c > 0) //valid
+ {
+ memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c);
+ }
+ 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..e3fc957fd2 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.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..ec36cf48c2 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -97,6 +97,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);
@@ -134,6 +135,9 @@ public:
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 );
@@ -175,6 +179,7 @@ protected:
LLFilterEditor* mFilterEdit;
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
+ PermissionMask mDnDFilterPermMask;
PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
@@ -184,12 +189,18 @@ protected:
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)
@@ -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)
@@ -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());
@@ -702,8 +716,7 @@ 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);
}
@@ -713,6 +726,7 @@ void LLFloaterTexturePicker::commitIfImmediateSet()
void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
if (self->mOwner)
{
self->setImageID( self->mOwner->getDefaultImageAssetID() );
@@ -724,6 +738,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata)
void LLFloaterTexturePicker::onBtnWhite(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
self->setImageID( self->mWhiteImageAssetID );
self->commitIfImmediateSet();
}
@@ -804,13 +819,17 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
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 +966,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 +977,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;
@@ -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);
@@ -1318,6 +1363,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);
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index 3abe84dcc3..599d9c70c5 100644
--- 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;
//////////////////////////////////////////////////////////////////////////////////////////
@@ -147,8 +148,12 @@ public:
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; }
@@ -172,6 +177,11 @@ public:
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,6 +195,7 @@ private:
drag_n_drop_callback mDropCallback;
commit_callback_t mOnCancelCallback;
commit_callback_t mOnSelectCallback;
+ texture_selected_callback mOnTextureSelectedCallback;
LLPointer<LLViewerFetchedTexture> mTexturep;
LLUIColor mBorderColor;
LLUUID mImageItemID;
@@ -198,6 +209,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 7e6dfbc9d9..a2854dd6d8 100755..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"
@@ -54,28 +54,214 @@
#include "llworld.h"
#include "llsdutil.h"
#include "llstartup.h"
-#include "llviewerstats.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);
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// 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
+
+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);
@@ -92,10 +278,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);
@@ -112,10 +302,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);
@@ -148,22 +342,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);
@@ -175,33 +382,93 @@ 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,
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,
@@ -209,8 +476,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,
@@ -254,9 +523,8 @@ private:
F32 mCacheReadTime;
LLTextureCache::handle_t mCacheReadHandle;
LLTextureCache::handle_t mCacheWriteHandle;
- U8* mBuffer;
- S32 mBufferSize;
S32 mRequestedSize;
+ S32 mRequestedOffset;
S32 mDesiredSize;
S32 mFileSize;
S32 mCachedSize;
@@ -271,10 +539,9 @@ private:
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
@@ -294,105 +561,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
};
//////////////////////////////////////////////////////////////////////////////
@@ -628,13 +809,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
@@ -650,6 +833,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
S32 discard, // Desired discard
S32 size) // Desired size
: LLWorkerClass(fetcher, "TextureFetch"),
+ LLCore::HttpHandler(),
mState(INIT),
mWriteToCacheState(NOT_WRITE),
mFetcher(fetcher),
@@ -667,9 +851,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
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),
@@ -683,19 +866,27 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
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;
@@ -714,7 +905,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);
@@ -725,10 +929,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());
@@ -738,6 +950,7 @@ void LLTextureFetchWorker::clearPackets()
mFirstPacket = 0;
}
+// Locks: Mw
void LLTextureFetchWorker::setupPacketData()
{
S32 data_size = 0;
@@ -770,6 +983,7 @@ void LLTextureFetchWorker::setupPacketData()
}
}
+// Locks: Mw (ctor invokes without lock)
U32 LLTextureFetchWorker::calcWorkPriority()
{
//llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority());
@@ -779,7 +993,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;
@@ -815,6 +1029,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
}
}
+// Locks: Mw
void LLTextureFetchWorker::setImagePriority(F32 priority)
{
// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
@@ -828,32 +1043,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)
{
- static const F32 FETCHING_TIMEOUT = 120.f;//seconds
-
- 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)))
{
@@ -897,15 +1117,20 @@ 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();
@@ -938,22 +1163,24 @@ 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())
+ 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))
{
@@ -961,7 +1188,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
llwarns << "Unknown URL Type: " << mUrl << llendl;
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- mState = SEND_HTTP_REQ;
+ mState = WAIT_HTTP_RESOURCE;
}
else
{
@@ -981,6 +1208,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
else
{
+ //
+ //This should never happen
+ //
return false;
}
}
@@ -1020,6 +1250,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
mState = LOAD_FROM_NETWORK;
}
+
// fall through
LLTextureFetch::sCacheHitRate.addValue(0.f);
}
@@ -1060,7 +1291,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
if (mCanUseHTTP && !mUrl.empty())
{
- mState = LLTextureFetchWorker::SEND_HTTP_REQ;
+ mState = WAIT_HTTP_RESOURCE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if(mWriteToCacheState != NOT_WRITE)
{
@@ -1077,13 +1308,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;
@@ -1094,12 +1319,7 @@ 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);
return false;
}
@@ -1124,196 +1344,250 @@ bool LLTextureFetchWorker::doWork(S32 param)
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mState = DECODE_IMAGE;
mWriteToCacheState = SHOULD_WRITE;
-
- if (mMetricsStartTime)
- {
- LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType,
- LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
- mMetricsStartTime = 0;
- }
- LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
- false,
- LLImageBase::TYPE_AVATAR_BAKE == mType);
+ 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())
+ {
+ mState = WAIT_HTTP_RESOURCE2;
+ setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+ mFetcher->addHttpWaiter(this->mID);
+ ++mResourceWaitCount;
+ return false;
+ }
+
+ mState = 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();
+ 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
- {
- return true ; //abort.
- }
+ // We already have all the data, just decode it
+ mLoadedDiscard = mFormattedImage->getDiscardLevel();
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ mState = 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())
- {
- mRequestedTimer.reset();
-
- 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();
+ 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);
+ mState = 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
+ {
+ mState = DONE;
+ releaseHttpSemaphore();
+ 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 ;
+ mState = 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)
- {
- if (cur_size > 0)
- {
- // Use available data
- mLoadedDiscard = mFormattedImage->getDiscardLevel();
- mState = DECODE_IMAGE;
- return false;
- }
- else
- {
- resetFormattedData();
- mState = DONE;
- return true; // failed
- }
- }
- else
+ mUrl.clear();
+ if (cur_size > 0)
{
- mState = SEND_HTTP_REQ;
- return false; // retry
+ // Use available data
+ mLoadedDiscard = mFormattedImage->getDiscardLevel();
+ setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ mState = DECODE_IMAGE;
+ releaseHttpSemaphore();
+ return false;
}
+
+ // Fail harder
+ resetFormattedData();
+ mState = DONE;
+ releaseHttpSemaphore();
+ 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)
+ {
+ 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.
+ // abort.
mState = DONE;
+ 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;
+ mState = 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
@@ -1325,44 +1599,49 @@ 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 (mWriteToCacheState != NOT_WRITE)
{
mWriteToCacheState = SHOULD_WRITE ;
}
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+ releaseHttpSemaphore();
return false;
}
else
{
- if(FETCHING_TIMEOUT < mRequestedTimer.getElapsedTimeF32())
- {
- //timeout, abort.
- mState = DONE;
- return true;
- }
+ // *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;
@@ -1372,11 +1651,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == DECODE_IMAGE)
{
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
- if(textures_decode_disabled)
+
+ 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);
return true;
}
@@ -1384,7 +1664,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// We aborted, don't decode
mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return true;
}
@@ -1394,7 +1673,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
//abort, don't decode
mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return true;
}
if (mLoadedDiscard < 0)
@@ -1403,10 +1681,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
//abort, don't decode
mState = DONE;
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
return true;
}
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
+
mRawImage = NULL;
mAuxImage = NULL;
llassert_always(mFormattedImage.notNull());
@@ -1492,10 +1769,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
U32 cache_priority = mWorkPriority;
mWritten = FALSE;
mState = 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
}
@@ -1536,9 +1814,84 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return false;
-}
+} // -Mw
-// Called from MAIN thread
+// Threads: Ttf
+// virtual
+void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+ 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") ;
+
+ 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());
+
+ lldebugs << "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)
@@ -1551,6 +1904,8 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
+
// virtual
void LLTextureFetchWorker::finishWork(S32 param, bool completed)
{
@@ -1567,10 +1922,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())
{
@@ -1605,6 +1987,7 @@ bool LLTextureFetchWorker::deleteOK()
return delete_ok;
}
+// Threads: Ttf
void LLTextureFetchWorker::removeFromCache()
{
if (!mInLocalCache)
@@ -1616,6 +1999,8 @@ void LLTextureFetchWorker::removeFromCache()
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
+// Locks: Mw
bool LLTextureFetchWorker::processSimulatorPackets()
{
if (mFormattedImage.isNull() || mRequestedSize < 0)
@@ -1676,14 +2061,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
@@ -1698,27 +2082,68 @@ 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)
{
// *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
@@ -1733,6 +2158,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
{
mRequestedSize = -1; // error
}
+
mLoaded = TRUE;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
@@ -1741,10 +2167,11 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
//////////////////////////////////////////////////////////////////////////////
+// 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;
@@ -1764,11 +2191,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;
@@ -1776,13 +2204,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
@@ -1815,10 +2244,11 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
// llinfos << mID << " : DECODE COMPLETE " << llendl;
setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
mCacheReadTime = mCacheReadTimer.getElapsedTimeF32();
-}
+} // -Mw
//////////////////////////////////////////////////////////////////////////////
+// Threads: Ttf
bool LLTextureFetchWorker::writeToCacheComplete()
{
// Complete write to cache
@@ -1841,6 +2271,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
@@ -1858,12 +2318,21 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
- mCurlGetRequest(NULL),
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"));
@@ -1871,12 +2340,27 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
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())
{
@@ -1884,10 +2368,34 @@ 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();
- // ~LLQueuedThread() called here
+ 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,
@@ -1940,6 +2448,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;
}
@@ -1951,7 +2461,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);
@@ -1960,41 +2470,44 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
if (!worker->haveWork())
{
worker->mState = LLTextureFetchWorker::INIT;
- worker->unlockWorkMutex();
+ 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() ;
+ 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;
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
@@ -2006,44 +2519,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))) ;
@@ -2051,15 +2572,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);
@@ -2068,34 +2599,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;
@@ -2107,14 +2661,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)
{
@@ -2137,7 +2693,7 @@ 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;
@@ -2148,11 +2704,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
}
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))
@@ -2162,7 +2718,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
raw = worker->mRawImage;
aux = worker->mAuxImage;
}
- worker->unlockWorkMutex();
+ worker->unlockWorkMutex(); // -Mw
}
}
else
@@ -2172,15 +2728,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;
@@ -2195,24 +2752,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()
{
@@ -2227,49 +2784,52 @@ 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");
{
- 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);
@@ -2281,7 +2841,7 @@ S32 LLTextureFetch::update(F32 max_time_ms)
// won't work so don't bother trying
if (LLStartUp::getStartupState() > STATE_AGENT_SEND)
{
- sendRequestListToSimulators();
+ sendRequestListToSimulators();
}
}
@@ -2290,10 +2850,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)
@@ -2303,7 +2870,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)
@@ -2313,35 +2882,27 @@ void LLTextureFetch::shutDownImageDecodeThread()
}
}
-// WORKER THREAD
+// Threads: Ttf
void LLTextureFetch::startThread()
{
- // Construct mCurlGetRequest from Worker Thread
- mCurlGetRequest = new LLCurlRequest();
-
- if(mFetchDebugger)
- {
- mFetchDebugger->setCurlGetRequest(mCurlGetRequest);
- }
}
-// WORKER THREAD
+// Threads: Ttf
void LLTextureFetch::endThread()
{
- // Destroy mCurlGetRequest from Worker Thread
- delete mCurlGetRequest;
- mCurlGetRequest = NULL;
- if(mFetchDebugger)
- {
- mFetchDebugger->setCurlGetRequest(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;
@@ -2350,9 +2911,10 @@ void LLTextureFetch::threadedUpdate()
return;
}
process_timer.reset();
+#endif
commonUpdate();
-
+
#if 0
const F32 INFO_TIME = 1.0f;
static LLFrameTimer info_timer;
@@ -2366,11 +2928,11 @@ void LLTextureFetch::threadedUpdate()
}
}
#endif
-
}
//////////////////////////////////////////////////////////////////////////////
+// Threads: Tmain
void LLTextureFetch::sendRequestListToSimulators()
{
// All requests
@@ -2396,48 +2958,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)
+ LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq
+ for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); )
{
- 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
+ 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)
@@ -2460,9 +3022,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)
{
@@ -2491,12 +3053,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)
{
@@ -2517,55 +3079,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();
@@ -2598,6 +3162,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
return true;
}
+// Threads: T*
bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
U16 data_size, U8* data)
{
@@ -2632,14 +3197,14 @@ 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;
}
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
// Copy header data into image object
worker->mImageCodec = codec;
@@ -2650,10 +3215,12 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
res = worker->insertPacket(0, data, data_size);
worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
- worker->unlockWorkMutex();
+ 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);
@@ -2678,14 +3245,14 @@ 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;
}
- worker->lockWorkMutex();
+ worker->lockWorkMutex(); // +Mw
res = worker->insertPacket(packet_num, data, data_size);
@@ -2702,7 +3269,7 @@ 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");
@@ -2714,12 +3281,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 ;
@@ -2727,14 +3296,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)
{
@@ -2748,7 +3318,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();
@@ -2775,7 +3345,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;
@@ -2799,12 +3369,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->mState = 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);
@@ -2812,6 +3589,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,
@@ -2822,6 +3600,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
@@ -2832,30 +3611,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)
@@ -2879,6 +3661,37 @@ 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_WARNS("Texture") << "Successfully delivered asset metrics to grid."
+ << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS("Texture") << "Error delivering asset metrics to grid. Reason: "
+ << status.toString() << LL_ENDL;
+ }
+ }
+}; // end class AssetReportHandler
+
+AssetReportHandler stats_handler;
+
+
/**
* Implements the 'Set Region' command.
*
@@ -2909,73 +3722,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;
@@ -3003,21 +3751,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
{
@@ -3075,6 +3828,7 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)
} // end of anonymous namespace
+
///////////////////////////////////////////////////////////////////////////////////////////
//Start LLTextureFetchDebugger
///////////////////////////////////////////////////////////////////////////////////////////
@@ -3128,47 +3882,13 @@ private:
S32 mID;
};
-class LLDebuggerHTTPResponder : public LLCurl::Responder
-{
-public:
- LLDebuggerHTTPResponder(LLTextureFetchDebugger* debugger, S32 index)
- : mDebugger(debugger), mIndex(index)
- {
- }
- virtual void completedRaw(U32 status, const std::string& reason,
- const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer)
- {
- 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)
- {
- llinfos << "Fetch Debugger : CURL GET FAILED, index = " << mIndex << ", status:" << status << " reason:" << reason << llendl;
- }
- mDebugger->callbackHTTP(mIndex, channels, buffer, partial, success);
- }
- virtual bool followRedir()
- {
- return true;
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mIndex;
-};
LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) :
mFetcher(fetcher),
mTextureCache(cache),
mImageDecodeThread(imagedecodethread),
- mCurlGetRequest(NULL)
+ mHttpHeaders(NULL),
+ mHttpPolicyClass(fetcher->getPolicyClass())
{
init();
}
@@ -3176,7 +3896,13 @@ LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextur
LLTextureFetchDebugger::~LLTextureFetchDebugger()
{
mFetchingHistory.clear();
- stopDebug();
+ mStopDebug = TRUE;
+ tryToStopDebug();
+ if (mHttpHeaders)
+ {
+ mHttpHeaders->release();
+ mHttpHeaders = NULL;
+ }
}
void LLTextureFetchDebugger::init()
@@ -3191,6 +3917,8 @@ void LLTextureFetchDebugger::init()
mTotalFetchingTime = 0.f;
mRefetchVisCacheTime = -1.f;
mRefetchVisHTTPTime = -1.f;
+ mRefetchAllCacheTime = -1.f;
+ mRefetchAllHTTPTime = -1.f;
mNumFetchedTextures = 0;
mNumCacheHits = 0;
@@ -3204,10 +3932,62 @@ void LLTextureFetchDebugger::init()
mRenderedDecodedData = 0;
mFetchedPixels = 0;
mRenderedPixels = 0;
- mRefetchedData = 0;
- mRefetchedPixels = 0;
+ mRefetchedVisData = 0;
+ mRefetchedVisPixels = 0;
+ mRefetchedAllData = 0;
+ mRefetchedAllPixels = 0;
mFreezeHistory = FALSE;
+ mStopDebug = FALSE;
+ mClearHistory = FALSE;
+
+ 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()
@@ -3215,10 +3995,18 @@ 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)
{
@@ -3230,6 +4018,11 @@ void LLTextureFetchDebugger::startDebug()
{
break;
}
+
+ if(mTimer.getElapsedTimeF32() > max_time)
+ {
+ return false;
+ }
}
//collect statistics
@@ -3268,10 +4061,17 @@ void LLTextureFetchDebugger::startDebug()
}
mNumFetchedTextures = fetched_textures.size();
+
+ return true;
}
-void LLTextureFetchDebugger::stopDebug()
+void LLTextureFetchDebugger::tryToStopDebug()
{
+ if(!mStopDebug)
+ {
+ return;
+ }
+
//clear the current debug work
S32 size = mFetchingHistory.size();
switch(mState)
@@ -3283,7 +4083,7 @@ void LLTextureFetchDebugger::stopDebug()
{
mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true);
}
- }
+ }
break;
case WRITE_CACHE:
for(S32 i = 0 ; i < size; i++)
@@ -3300,37 +4100,72 @@ void LLTextureFetchDebugger::stopDebug()
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;
}
- while(1)
+ if(update(0.005f))
{
- if(update())
+ //unlock the fetcher
+ mFetcher->lockFetcher(false);
+ mFetcher->resetLoadSource();
+ mFreezeHistory = FALSE;
+ mStopDebug = FALSE;
+
+ if(mClearHistory)
{
- break;
+ mFetchingHistory.clear();
+ mHandleToFetchIndex.clear();
+ init();
+ mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset
}
}
-
- //unlock the fetcher
- mFetcher->lockFetcher(false);
- mFreezeHistory = FALSE;
- mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset
}
//called in the main thread and when the fetching queue is empty
void LLTextureFetchDebugger::clearHistory()
{
- mFetchingHistory.clear();
- init();
+ mClearHistory = TRUE;
}
void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
{
+ if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull())
+ {
+ return;
+ }
+
if(mFreezeHistory)
{
- mRefetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
- mRefetchedData += worker->mFormattedImage->getDataSize();
+ 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;
}
@@ -3342,9 +4177,8 @@ void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
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()));
- //mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mHaveAllData ? 0 : worker->mLoadedDiscard, worker->mFormattedImage->getComponents(),
- //worker->mDecodedDiscard, worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
+ mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,
+ worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
}
void LLTextureFetchDebugger::lockCache()
@@ -3361,6 +4195,7 @@ void LLTextureFetchDebugger::debugCacheRead()
llassert_always(mState == IDLE);
mTimer.reset();
mState = READ_CACHE;
+ mCacheReadTime = -1.f;
S32 size = mFetchingHistory.size();
for(S32 i = 0 ; i < size ; i++)
@@ -3396,6 +4231,7 @@ void LLTextureFetchDebugger::debugCacheWrite()
llassert_always(mState == IDLE);
mTimer.reset();
mState = WRITE_CACHE;
+ mCacheWriteTime = -1.f;
S32 size = mFetchingHistory.size();
for(S32 i = 0 ; i < size ; i++)
@@ -3405,7 +4241,7 @@ void LLTextureFetchDebugger::debugCacheWrite()
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,
- new LLDebuggerCacheWriteResponder(this, i));
+ NULL, 0, new LLDebuggerCacheWriteResponder(this, i));
}
}
}
@@ -3424,6 +4260,7 @@ void LLTextureFetchDebugger::debugDecoder()
llassert_always(mState == IDLE);
mTimer.reset();
mState = DECODING;
+ mDecodingTime = -1.f;
S32 size = mFetchingHistory.size();
for(S32 i = 0 ; i < size ; i++)
@@ -3459,6 +4296,7 @@ void LLTextureFetchDebugger::debugHTTP()
mTimer.reset();
mState = HTTP_FETCHING;
+ mHTTPTime = -1.f;
S32 size = mFetchingHistory.size();
for (S32 i = 0 ; i < size ; i++)
@@ -3466,6 +4304,7 @@ void LLTextureFetchDebugger::debugHTTP()
mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE;
mFetchingHistory[i].mCurlReceivedSize = 0;
mFetchingHistory[i].mHTTPFailCount = 0;
+ mFetchingHistory[i].mFormattedImage = NULL;
}
mNbCurlRequests = 0;
mNbCurlCompleted = 0;
@@ -3475,30 +4314,51 @@ void LLTextureFetchDebugger::debugHTTP()
S32 LLTextureFetchDebugger::fillCurlQueue()
{
- if (mNbCurlRequests == 24)
+ 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++)
{
+ mNbCurlRequests++;
+
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);
- std::vector<std::string> headers;
- headers.push_back("Accept: image/x-j2c");
- bool res = mCurlGetRequest->getByteRange(texture_url, headers, 0, requestedSize, new LLDebuggerHTTPResponder(this, i));
- if (res)
+
+ 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++;
// Hack
- if (mNbCurlRequests == 24)
+ if (mNbCurlRequests == HTTP_REQUESTS_IN_QUEUE_HIGH_WATER) // emulate normal pipeline
+ {
break;
+ }
}
else
{
@@ -3513,7 +4373,7 @@ void LLTextureFetchDebugger::debugGLTextureCreation()
{
llassert_always(mState == IDLE);
mState = GL_TEX;
- std::vector<LLViewerFetchedTexture*> tex_list;
+ mTempTexList.clear();
S32 size = mFetchingHistory.size();
for(S32 i = 0 ; i < size ; i++)
@@ -3524,28 +4384,54 @@ void LLTextureFetchDebugger::debugGLTextureCreation()
if(tex && !tex->isForSculptOnly())
{
tex->destroyGLTexture() ;
- tex_list.push_back(tex);
+ mTempTexList.push_back(tex);
}
}
}
+
+ mGLCreationTime = -1.f;
+ mTempIndex = 0;
+ mHistoryListIndex = 0;
+
+ return;
+}
+bool LLTextureFetchDebugger::processGLCreation(F32 max_time)
+{
mTimer.reset();
- S32 j = 0 ;
- S32 size1 = tex_list.size();
- for(S32 i = 0 ; i < size && j < size1; i++)
+
+ bool done = true;
+ S32 size = mFetchingHistory.size();
+ S32 size1 = mTempTexList.size();
+ for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)
{
- if(mFetchingHistory[i].mRawImage.notNull())
+ if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())
{
- if(mFetchingHistory[i].mID == tex_list[j]->getID())
+ if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())
{
- tex_list[j]->createGLTexture(mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mRawImage, 0, TRUE, tex_list[j]->getBoostLevel());
- j++;
+ mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,
+ mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel());
+ mTempIndex++;
}
}
+
+ if(mTimer.getElapsedTimeF32() > max_time)
+ {
+ done = false;
+ break;
+ }
}
- mGLCreationTime = mTimer.getElapsedTimeF32() ;
- return;
+ if(mGLCreationTime < 0.f)
+ {
+ mGLCreationTime = mTimer.getElapsedTimeF32() ;
+ }
+ else
+ {
+ mGLCreationTime += mTimer.getElapsedTimeF32() ;
+ }
+
+ return done;
}
//clear fetching results of all textures.
@@ -3562,15 +4448,62 @@ void LLTextureFetchDebugger::clearTextures()
}
}
+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()
@@ -3578,17 +4511,60 @@ void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()
llassert_always(mState == IDLE);
mState = REFETCH_VIS_HTTP;
- clearCache();
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;
}
-bool LLTextureFetchDebugger::update()
+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))
{
@@ -3614,8 +4590,8 @@ bool LLTextureFetchDebugger::update()
}
break;
case HTTP_FETCHING:
- mCurlGetRequest->process();
- LLCurl::getCurlThread()->update(1);
+ // Do some notifications...
+ mFetcher->getHttpRequest().update(10);
if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())
{
mHTTPTime = mTimer.getElapsedTimeF32() ;
@@ -3623,22 +4599,59 @@ bool LLTextureFetchDebugger::update()
}
break;
case GL_TEX:
- mState = IDLE;
+ if(processGLCreation(max_time))
+ {
+ mState = IDLE;
+ mTempTexList.clear();
+ }
break;
case REFETCH_VIS_CACHE:
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
{
- mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime;
+ mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;
mState = IDLE;
mFetcher->lockFetcher(true);
+ mFetcher->resetLoadSource();
}
break;
case REFETCH_VIS_HTTP:
if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
{
- mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime;
+ 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:
@@ -3649,6 +4662,28 @@ bool LLTextureFetchDebugger::update()
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)
{
@@ -3675,50 +4710,60 @@ void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* r
}
}
-void LLTextureFetchDebugger::callbackHTTP(S32 id, const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer,
- bool partial, bool success)
+void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response)
{
+ static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT);
+
+ LLCore::HttpStatus status(response->getStatus());
mNbCurlRequests--;
- if (success)
+ if (status)
{
- mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE;
+ const bool partial(par_status == status);
+ LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body
+
+ fetch.mCurlState = FetchEntry::CURL_DONE;
mNbCurlCompleted++;
- S32 data_size = buffer->countAfter(channels.in(), NULL);
- mFetchingHistory[id].mCurlReceivedSize += data_size;
- //llinfos << "Fetch Debugger : got results for " << id << ", data_size = " << data_size << ", received = " << mFetchingHistory[id].mCurlReceivedSize << ", requested = " << mFetchingHistory[id].mRequestedSize << ", partial = " << partial << llendl;
- if ((mFetchingHistory[id].mCurlReceivedSize >= mFetchingHistory[id].mRequestedSize) || !partial || (mFetchingHistory[id].mRequestedSize == 600))
+ 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);
- buffer->readAfter(channels.in(), NULL, d_buffer, data_size);
+ if (ba)
+ {
+ ba->read(0, d_buffer, data_size);
+ }
- llassert_always(mFetchingHistory[id].mFormattedImage.isNull());
+ llassert_always(fetch.mFormattedImage.isNull());
{
// For now, create formatted image based on extension
- std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[id].mID.asString().c_str();
+ std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str();
std::string extension = gDirUtilp->getExtension(texture_url);
- mFetchingHistory[id].mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
- if (mFetchingHistory[id].mFormattedImage.isNull())
+ fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
+ if (fetch.mFormattedImage.isNull())
{
- mFetchingHistory[id].mFormattedImage = new LLImageJ2C; // default
+ fetch.mFormattedImage = new LLImageJ2C; // default
}
}
- mFetchingHistory[id].mFormattedImage->setData(d_buffer, data_size);
+ fetch.mFormattedImage->setData(d_buffer, data_size);
}
}
else //failed
{
- mFetchingHistory[id].mHTTPFailCount++;
- if(mFetchingHistory[id].mHTTPFailCount < 5)
+ llinfos << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID
+ << ", status: " << status.toHex()
+ << " reason: " << status.toString() << llendl;
+ fetch.mHTTPFailCount++;
+ if(fetch.mHTTPFailCount < 5)
{
// Fetch will have to be redone
- mFetchingHistory[id].mCurlState = FetchEntry::CURL_NOT_DONE;
+ fetch.mCurlState = FetchEntry::CURL_NOT_DONE;
}
else //skip
{
- mFetchingHistory[id].mCurlState = FetchEntry::CURL_DONE;
+ fetch.mCurlState = FetchEntry::CURL_DONE;
mNbCurlCompleted++;
}
}
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 107e1623b0..3a99432b48 100644
--- 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,19 +27,24 @@
#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 "lltexturecache.h"
+#include "llcurl.h"
+#include "httprequest.h"
+#include "httpoptions.h"
+#include "httpheaders.h"
+#include "httphandler.h"
class LLViewerTexture;
class LLTextureFetchWorker;
-class HTTPGetResponder;
class LLImageDecodeThread;
class LLHost;
class LLViewerAssetStats;
@@ -47,10 +52,10 @@ 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);
@@ -58,72 +63,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();
+ //called in the main thread after the ImageDecodeThread shuts down.
+ // Threads: Tmain
+ void shutDownImageDecodeThread();
+
+ // Threads: T* (but Tmain mostly)
bool createRequest(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
@@ -134,6 +268,8 @@ private:
* Takes ownership of the TFRequest object.
*
* Method locks the command queue.
+ *
+ * Threads: T*
*/
void cmdEnqueue(TFRequest *);
@@ -144,6 +280,8 @@ private:
* Caller acquires ownership of the object and must dispose of it.
*
* Method locks the command queue.
+ *
+ * Threads: T*
*/
TFRequest * cmdDequeue();
@@ -153,6 +291,8 @@ private:
* additional commands.
*
* Method locks the command queue.
+ *
+ * Threads: Ttf
*/
void cmdDoWork();
@@ -172,43 +312,64 @@ private:
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
@@ -216,19 +377,35 @@ public:
// 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 LLTextureFetchDebugger
+class LLViewerFetchedTexture;
+class LLTextureFetchDebugger : public LLCore::HttpHandler
{
friend class LLTextureFetch;
public:
@@ -239,6 +416,7 @@ public:
enum e_debug_state
{
IDLE = 0,
+ START_DEBUG,
READ_CACHE,
WRITE_CACHE,
DECODING,
@@ -272,11 +450,13 @@ private:
e_curl_state mCurlState;
S32 mCurlReceivedSize;
S32 mHTTPFailCount;
+ LLCore::HttpHandle mHttpHandle;
FetchEntry() :
mDecodedLevel(-1),
mFetchedSize(0),
- mDecodedSize(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),
@@ -285,10 +465,15 @@ private:
mFetchedSize(f_size),
mDecodedSize(d_size),
mNeedsAux(false),
- mHTTPFailCount(0)
+ mHTTPFailCount(0),
+ mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
{}
};
- std::vector<FetchEntry> mFetchingHistory;
+ 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;
@@ -301,13 +486,16 @@ private:
F32 mTotalFetchingTime;
F32 mRefetchVisCacheTime;
F32 mRefetchVisHTTPTime;
+ F32 mRefetchAllCacheTime;
+ F32 mRefetchAllHTTPTime;
LLTimer mTimer;
LLTextureFetch* mFetcher;
LLTextureCache* mTextureCache;
LLImageDecodeThread* mImageDecodeThread;
- LLCurlRequest* mCurlGetRequest;
+ LLCore::HttpHeaders* mHttpHeaders;
+ LLCore::HttpRequest::policy_t mHttpPolicyClass;
S32 mNumFetchedTextures;
S32 mNumCacheHits;
@@ -321,42 +509,44 @@ private:
U32 mRenderedDecodedData;
U32 mFetchedPixels;
U32 mRenderedPixels;
- U32 mRefetchedData;
- U32 mRefetchedPixels;
+ 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(); //called in the main thread once per frame
+ bool update(F32 max_time); //called in the main thread once per frame
//fetching history
void clearHistory();
void addHistoryEntry(LLTextureFetchWorker* worker);
- void setCurlGetRequest(LLCurlRequest* request) { mCurlGetRequest = request;}
-
- void startDebug();
- void stopDebug(); //stop everything
- void debugCacheRead();
- void debugCacheWrite();
- void debugHTTP();
- void debugDecoder();
- void debugGLTextureCreation();
- void debugRefetchVisibleFromCache();
- void debugRefetchVisibleFromHTTP();
+ // 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(S32 id, const LLChannelDescriptors& channels,
- const LLIOPipe::buffer_ptr_t& buffer,
- bool partial, bool success);
-
+ void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response);
e_debug_state getState() {return mState;}
S32 getNumFetchedTextures() {return mNumFetchedTextures;}
@@ -372,8 +562,10 @@ public:
U32 getRenderedDecodedData() {return mRenderedDecodedData;}
U32 getFetchedPixels() {return mFetchedPixels;}
U32 getRenderedPixels() {return mRenderedPixels;}
- U32 getRefetchedData() {return mRefetchedData;}
- U32 getRefetchedPixels() {return mRefetchedPixels;}
+ U32 getRefetchedVisData() {return mRefetchedVisData;}
+ U32 getRefetchedVisPixels() {return mRefetchedVisPixels;}
+ U32 getRefetchedAllData() {return mRefetchedAllData;}
+ U32 getRefetchedAllPixels() {return mRefetchedAllPixels;}
F32 getCacheReadTime() {return mCacheReadTime;}
F32 getCacheWriteTime() {return mCacheWriteTime;}
@@ -383,11 +575,15 @@ public:
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();
@@ -400,6 +596,20 @@ private:
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:
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 425bf7ee87..16c42dbd43 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
@@ -74,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;
////////////////////////////////////////////////////////////////////////////
@@ -232,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
@@ -239,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
@@ -345,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);
@@ -510,18 +512,22 @@ void LLGLTexMemBar::draw()
F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
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 = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
+ S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
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);
@@ -531,14 +537,26 @@ void LLGLTexMemBar::draw()
bound_mem,
max_bound_mem,
LLRenderTarget::sBytesAllocated/(1024*1024),
- LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
- cache_usage, cache_max_usage);
+ 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*4,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- text = llformat("Net Tot Tex: %.1f MB Tot Obj: %.1f MB Tot Htp: %d",
- total_texture_downloaded, total_object_downloaded, total_http_requests);
- //, cache_entries, cache_max_entries
+ U32 cache_read(0U), cache_write(0U), res_wait(0U);
+ LLAppViewer::getTextureFetch()->getStateStats(&cache_read, &cache_write, &res_wait);
+
+ 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);
+
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 0eec7f0afd..9dfb29b905 100644
--- 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);
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index a473ee7ce0..602b924398 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -334,32 +334,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);
@@ -457,7 +449,7 @@ button_name_set_t getButtonDisableList(const std::string& notification_name, con
{
search_map = user_give_item_disable_map;
}
- else if("TeleportOffered" == notification_name)
+ else if(("TeleportOffered" == notification_name) || ("TeleportOffered_MaturityExceeded" == notification_name))
{
search_map = teleport_offered_disable_map;
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 4f4eef0f3d..c69999981c 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1007,7 +1007,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 +1029,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
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 245c2a23e6..41aee484db 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -93,6 +93,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 +226,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/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 319e2508e0..9907da0f0e 100644
--- 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/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index ac01316462..a135ba70f5 100644
--- 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
--- 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..0d5daf129f 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -225,7 +225,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/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index b0d9bd5d70..3cd761b73b 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -312,7 +312,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 +596,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);
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index bf1f8808a7..cbd16e873d 100644
--- 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/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/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 4240a38326..00b15a5f26 100644
--- 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/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 2447f5dea8..8d8c401dac 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -41,6 +41,7 @@
#include "llstartup.h"
#include "llviewerparcelmgr.h"
#include "llparcel.h"
+#include "llviewermessage.h"
/////////////////////////////////////////////////////////
@@ -49,15 +50,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 +75,6 @@ void LLViewerAudio::registerIdleListener()
mIdleListnerActive = true;
doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
}
-
}
void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
@@ -245,16 +252,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()
@@ -360,15 +405,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);
}
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index a3da9fc6b8..8c302c6549 100644
--- 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.h b/indra/newview/llviewercamera.h
index 184033de42..b857c7fe89 100644
--- 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/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index f2712e7590..dec1615246 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -71,8 +71,12 @@
#include "llpaneloutfitsinventory.h"
#include "llpanellogin.h"
#include "llpaneltopinfobar.h"
+#include "llspellcheck.h"
#include "llupdaterservice.h"
+// Third party library includes
+#include <boost/algorithm/string.hpp>
+
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
#endif
@@ -325,7 +329,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;
}
@@ -337,15 +341,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())
@@ -501,6 +496,25 @@ bool handleForceShowGrid(const LLSD& newvalue)
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() )
@@ -637,7 +651,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));
@@ -706,6 +719,8 @@ 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));
}
#if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 0adb187dd2..d58ee05fb6 100644
--- 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;
@@ -162,8 +163,11 @@ void display_startup()
glClear(GL_DEPTH_BUFFER_BIT);
}
+static LLFastTimer::DeclareTimer FTM_UPDATE_CAMERA("Update Camera");
+
void display_update_camera()
{
+ LLFastTimer t(FTM_UPDATE_CAMERA);
LLMemType mt_uc(LLMemType::MTYPE_DISPLAY_UPDATE_CAMERA);
// TODO: cut draw distance down if customizing avatar?
// TODO: cut draw distance on per-parcel basis?
@@ -217,6 +221,11 @@ static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class");
static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("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)
@@ -226,6 +235,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
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();
@@ -362,6 +372,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 +394,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 +436,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:
@@ -581,6 +602,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
// *TODO: merge these two methods
{
+ LLFastTimer t(FTM_HUD_UPDATE);
LLMemType mt_uh(LLMemType::MTYPE_DISPLAY_UPDATE_HUD);
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
@@ -588,6 +610,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
{
+ LLFastTimer t(FTM_DISPLAY_UPDATE_GEOM);
LLMemType mt_ug(LLMemType::MTYPE_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);
@@ -597,6 +620,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
gPipeline.updateGL();
+
stop_glerror();
S32 water_clip = 0;
@@ -622,11 +646,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
@@ -755,13 +774,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();
@@ -889,6 +908,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
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)
{
@@ -911,14 +952,18 @@ 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)
@@ -984,6 +1029,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
display_stats();
LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
+
+ gShiftFrame = false;
}
void render_hud_attachments()
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index d0e0d0d826..1f7cf0cdd4 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -30,7 +30,7 @@
#include "llfloaterreg.h"
#include "llviewerfloaterreg.h"
-
+#include "llfloaterautoreplacesettings.h"
#include "llcompilequeue.h"
#include "llcallfloater.h"
#include "llfasttimerview.h"
@@ -78,12 +78,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"
@@ -100,6 +102,7 @@
#include "llfloatersidepanelcontainer.h"
#include "llfloatersnapshot.h"
#include "llfloatersounddevices.h"
+#include "llfloaterspellchecksettings.h"
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
#include "llfloatertestlistview.h"
@@ -249,12 +252,18 @@ 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("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("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
@@ -304,7 +313,6 @@ void LLViewerFloaterReg::registerFloaters()
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");
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
index a8a918f259..04c2e27c9d 100644
--- 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/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 4e14824e69..3a04bbed4f 100644
--- 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/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index f029ae5302..5d1aa870a3 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -729,8 +729,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/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 1eb4bedfaf..47059b0b8c 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1184,12 +1184,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 +1194,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))
{
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 34e916fec0..5a8ef00b1f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -60,6 +60,8 @@
#include "llfloatergodtools.h"
#include "llfloaterinventory.h"
#include "llfloaterland.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llfloaterpathfindinglinksets.h"
#include "llfloaterpay.h"
#include "llfloaterreporter.h"
#include "llfloatersearch.h"
@@ -81,11 +83,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"
@@ -116,6 +120,7 @@
#include "lleconomy.h"
#include "lltoolgrab.h"
#include "llwindow.h"
+#include "llpathfindingmanager.h"
#include "boost/unordered_map.hpp"
using namespace LLVOAvatarDefines;
@@ -203,7 +208,6 @@ 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, LLObjectSelectionHandle selection_handle);
@@ -300,7 +304,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*);
@@ -1643,23 +1646,6 @@ class LLAdvancedTestFemale : public view_listener_t
}
};
-
-
-///////////////
-// TOGGLE PG //
-///////////////
-
-
-class LLAdvancedTogglePG : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- handle_toggle_pg(NULL);
- return true;
- }
-};
-
-
class LLAdvancedForceParamsToDefault : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -2039,7 +2025,6 @@ class LLAdvancedCompressImage : public view_listener_t
};
-
/////////////////////////
// SHOW DEBUG SETTINGS //
/////////////////////////
@@ -2800,6 +2785,16 @@ 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)
@@ -3321,7 +3316,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();
@@ -4199,8 +4194,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;
}
@@ -4610,9 +4606,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;
}
@@ -4864,6 +4861,53 @@ class LLToolsSaveToObjectInventory : public view_listener_t
}
};
+class LLToolsEnablePathfinding : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ 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)
+ {
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
+ }
+
+ 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;
+ }
+};
+
// Round the position of all root objects to the grid
class LLToolsSnapObjectXY : public view_listener_t
{
@@ -5122,6 +5166,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 =
@@ -5137,6 +5259,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()
{
@@ -5367,6 +5532,14 @@ void toggle_debug_menus(void*)
// }
//
+class LLCommunicateBlockList : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+ return true;
+ }
+};
class LLWorldSetHomeLocation : public view_listener_t
{
@@ -6490,6 +6663,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);
}
@@ -6738,15 +6912,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;
@@ -7006,8 +7171,8 @@ BOOL enable_save_into_inventory(void*)
return TRUE;
}
}
-#endif
return FALSE;
+#endif
}
class LLToolsEnableSaveToInventory : public view_listener_t
@@ -8072,6 +8237,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.
@@ -8153,6 +8331,9 @@ void initialize_menus()
// Me > Movement
view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
+ // Communicate
+ view_listener_t::addMenu(new LLCommunicateBlockList(), "Communicate.BlockList");
+
// World menu
view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
@@ -8208,6 +8389,11 @@ void initialize_menus()
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");
@@ -8311,7 +8497,6 @@ void initialize_menus()
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 (toplevel)
view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
@@ -8498,6 +8683,10 @@ void initialize_menus()
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
enable.add("EnableEdit", boost::bind(&enable_object_edit));
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..3515aa4302 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -39,6 +39,7 @@ class LLObjectSelection;
class LLSelectNode;
void initialize_edit_menu();
+void initialize_spellcheck_menu();
void init_menus();
void cleanup_menus();
@@ -93,11 +94,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();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a9bff67f40..b048332e59 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -42,6 +42,7 @@
#include "llinventorydefines.h"
#include "lllslconstants.h"
#include "llregionhandle.h"
+#include "llsd.h"
#include "llsdserialize.h"
#include "llteleportflags.h"
#include "lltransactionflags.h"
@@ -107,6 +108,7 @@
#include "llagentui.h"
#include "llpanelblockedlist.h"
#include "llpanelplaceprofile.h"
+#include "llviewerregion.h"
#include <boost/algorithm/string/split.hpp> //
#include <boost/regex.hpp>
@@ -132,6 +134,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);
@@ -1992,6 +1995,46 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
}
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();
@@ -2770,7 +2813,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;
@@ -2795,7 +2842,7 @@ 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)
+ if(!chat_from_system && nearby_chat)
{
chat.mOwnerID = from_id;
LLSD args;
@@ -2814,7 +2861,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;
@@ -2879,15 +2926,54 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
{
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))
{
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,28 +2982,130 @@ 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("TeleportOffered");
+ params.substitutions = args;
+ params.payload = payload;
+ LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false);
+ }
- 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;
- // do not show a message box, because you're about to be
- // teleported.
- LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
+ 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;
@@ -3152,9 +3340,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:
@@ -3441,6 +3629,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 +3651,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;
@@ -3734,6 +3931,7 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
void process_agent_movement_complete(LLMessageSystem* msg, void**)
{
+ gShiftFrame = true;
gAgentMovementCompleted = true;
LLUUID agent_id;
@@ -4064,6 +4262,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 +4272,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") << " head rot " << head_rotation << 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,9 +4293,9 @@ 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;
}
-*/
+ */
duplicate_count = 0;
}
@@ -4129,6 +4330,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);
@@ -4297,8 +4518,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))
{
@@ -4321,6 +4540,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
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 +4855,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;
@@ -4739,7 +4976,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 +5123,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");
@@ -5389,23 +5626,35 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
}
}
-
-
-bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
+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
- int preferredMaturity = notification["payload"]["_region_access"].asInteger();
- gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
- gAgent.sendMaturityPreferenceToServer(preferredMaturity);
+ U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger());
+ gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity));
+ }
+
+ return false;
+}
- // notify user that the maturity preference has been changed
- LLSD args;
- args["RATING"] = LLViewerRegion::accessToString(preferredMaturity);
- LLNotificationsUtil::add("PreferredMaturityChanged", args);
+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
+ 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 +5663,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;
}
}
- return false;
+
+ 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;
}
bool attempt_standard_notification(LLMessageSystem* msgsystem)
@@ -5490,16 +5848,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))
@@ -5551,6 +5913,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
}
}
+bool handle_not_age_verified_alert(const std::string &pAlertName)
+{
+ LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName);
+ if ((notification == NULL) || notification->isIgnored())
+ {
+ LLNotificationsUtil::add(pAlertName + "_Notify");
+ }
+
+ return true;
+}
+
+bool handle_special_alerts(const std::string &pAlertName)
+{
+ bool isHandled = false;
+
+ if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0)
+ {
+
+ isHandled = handle_not_age_verified_alert(pAlertName);
+ }
+
+ return isHandled;
+}
+
void process_alert_core(const std::string& message, BOOL modal)
{
// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
@@ -5574,7 +5960,10 @@ 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()));
- LLNotificationsUtil::add(alert_name);
+ if (!handle_special_alerts(alert_name))
+ {
+ LLNotificationsUtil::add(alert_name);
+ }
}
else if (message.find(NOTIFY_PREFIX) == 0)
{
@@ -6160,6 +6549,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)
{
@@ -6189,7 +6581,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 )
{
@@ -6218,9 +6610,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 );
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 46bfb2dad0..594c22ed9c 100644
--- 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
//
@@ -205,6 +208,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
{
@@ -253,5 +265,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..97f4c3e5fe 100644
--- 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,39 @@
#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";
+///
+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 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 +80,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 +103,83 @@ 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,
+ "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,
+ "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 +188,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,115 +231,105 @@ 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& login_id)
@@ -432,12 +339,12 @@ 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_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 +354,187 @@ 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
-
- // 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))
+ LL_DEBUGS("GridManager")<<"requested "<<grid<<LL_ENDL;
+ std::string grid_name = getGrid(grid); // resolved either the name or the id to the 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());
+ }
}
- 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;
}
}
-std::string LLGridManager::getHelperURI()
+void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
{
- std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
- if(!cmd_line_helper_uri.empty())
+ 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())
{
- return cmd_line_helper_uri;
+ helper_uri = mGridList[grid_name][GRID_HELPER_URI_VALUE].asString();
}
- return mGridList[mGrid][GRID_HELPER_URI_VALUE];
+ else
+ {
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+ }
+
+ LL_DEBUGS("GridManager")<<"returning "<<helper_uri<<LL_ENDL;
+ return helper_uri;
}
-std::string LLGridManager::getLoginPage()
+std::string LLGridManager::getLoginPage(const std::string& grid)
{
- // override the login page if it was passed in
- std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
- if(!cmd_line_login_page.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_login_page;
- }
-
- return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];
+ LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+ }
+ 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::getGridLoginID()
+{
+ return mGridList[mGrid][GRID_ID_VALUE];
}
void LLGridManager::updateIsInProductionGrid()
@@ -578,13 +548,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 +569,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))
+ std::string grid_base = "";
+ std::string grid_name = getGrid(grid);
+ if( ! grid_name.empty() && mGridList.has(grid_name) )
{
- return mGridList[grid][GRID_SLURL_BASE].asString();
- }
- else
- {
- 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))
- {
- return mGridList[grid][GRID_APP_SLURL_BASE].asString();
- }
- else
+ std::string grid_base = "";
+ std::string grid_name = getGrid(grid);
+ if(!grid_name.empty() && mGridList.has(grid))
{
- 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..3f56103b2e 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -27,113 +27,181 @@
#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();
- 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]; }
- // build a slurl for the given region within the selected grid
+ /// 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();
+
+ /// 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 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,
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index cd300accb7..b2bd547811 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -199,6 +199,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mID(id),
mLocalID(0),
mTotalCRC(0),
+ mListIndex(-1),
mTEImages(NULL),
mGLName(0),
mbCanSelect(TRUE),
@@ -235,7 +236,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),
@@ -265,6 +267,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
{
mPositionAgent = mRegionp->getOriginAgent();
}
+ resetRot();
LLViewerObject::sNumObjects++;
}
@@ -280,12 +283,6 @@ LLViewerObject::~LLViewerObject()
mInventory = NULL;
}
- if (mJointInfo)
- {
- delete mJointInfo;
- mJointInfo = NULL;
- }
-
if (mPartSourcep)
{
mPartSourcep->setDead();
@@ -336,9 +333,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
@@ -432,7 +426,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)
@@ -446,7 +442,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;
@@ -739,7 +735,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);
}
@@ -790,6 +786,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()))
@@ -1230,12 +1232,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())
{
@@ -1292,26 +1290,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;
}
@@ -1429,9 +1407,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:
@@ -1455,9 +1434,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;
}
@@ -1529,9 +1509,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:
@@ -1575,8 +1556,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if (value & 0x80)
{
- dp->unpackVector3(vec, "Omega");
- setAngularVelocity(vec);
+ dp->unpackVector3(new_angv, "Omega");
+ setAngularVelocity(new_angv);
}
if (value & 0x20)
@@ -1959,14 +1940,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())
@@ -2065,21 +2038,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;
@@ -2094,9 +2079,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!
}
@@ -2167,17 +2158,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())
@@ -2186,88 +2173,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)
+ if (isAttachment())
{
- 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)
- {
- // 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
@@ -2276,8 +2187,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
}
updateDrawable(FALSE);
-
- return TRUE;
+ }
}
@@ -2389,10 +2299,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);
@@ -2798,6 +2709,23 @@ void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtS
(object = gObjectList.findObject(ft->mTaskID)))
{
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
{
@@ -2904,13 +2832,40 @@ 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.
@@ -3822,15 +3777,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);
@@ -3844,8 +3790,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;
}
@@ -4038,38 +3983,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()
{
@@ -4158,7 +4071,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
return retval;
}
-
+//virtual
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
if(index < 0 || index >= getNumTEs())
@@ -4477,7 +4390,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;
@@ -4492,7 +4409,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;
@@ -4578,19 +4499,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();
}
@@ -4769,9 +4682,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...
@@ -5136,7 +5051,7 @@ BOOL LLViewerObject::permAnyOwner() const
{
if (isRootEdit())
{
- return ((mFlags & FLAGS_OBJECT_ANY_OWNER) != 0);
+ return flagObjectAnyOwner();
}
else
{
@@ -5158,7 +5073,7 @@ BOOL LLViewerObject::permYouOwner() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_YOU_OWNER) != 0);
+ return flagObjectYouOwner();
#endif
}
else
@@ -5172,7 +5087,7 @@ BOOL LLViewerObject::permGroupOwner() const
{
if (isRootEdit())
{
- return ((mFlags & FLAGS_OBJECT_GROUP_OWNED) != 0);
+ return flagObjectGroupOwned();
}
else
{
@@ -5195,7 +5110,7 @@ BOOL LLViewerObject::permOwnerModify() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_OWNER_MODIFY) != 0);
+ return flagObjectOwnerModify();
#endif
}
else
@@ -5219,7 +5134,7 @@ BOOL LLViewerObject::permModify() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_MODIFY) != 0);
+ return flagObjectModify();
#endif
}
else
@@ -5243,7 +5158,7 @@ BOOL LLViewerObject::permCopy() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_COPY) != 0);
+ return flagObjectCopy();
#endif
}
else
@@ -5267,7 +5182,7 @@ BOOL LLViewerObject::permMove() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_MOVE) != 0);
+ return flagObjectMove();
#endif
}
else
@@ -5291,7 +5206,7 @@ BOOL LLViewerObject::permTransfer() const
return TRUE;
}
# endif
- return ((mFlags & FLAGS_OBJECT_TRANSFER) != 0);
+ return flagObjectTransfer();
#endif
}
else
@@ -5334,21 +5249,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)
@@ -5387,8 +5300,8 @@ void LLViewerObject::updateRegion(LLViewerRegion *regionp)
bool LLViewerObject::specialHoverCursor() const
{
- return (mFlags & FLAGS_USE_PHYSICS)
- || (mFlags & FLAGS_HANDLE_TOUCH)
+ return flagUsePhysics()
+ || flagHandleTouch()
|| (mClickAction != 0);
}
@@ -5401,10 +5314,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");
@@ -5419,6 +5337,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)
{
@@ -5436,22 +5367,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)
{
@@ -5477,7 +5404,6 @@ U8 LLViewerObject::getPhysicsShapeType() const
{
if (mPhysicsShapeUnknown)
{
- mPhysicsShapeUnknown = false;
gObjectList.updatePhysicsFlags(this);
}
@@ -5499,18 +5425,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;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index c8152e1539..1fb30db8f2 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -88,18 +88,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
{
@@ -157,7 +145,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 };
@@ -188,8 +176,6 @@ public:
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) { mUserSelected = sel; resetRot();}
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; }
@@ -308,7 +299,6 @@ 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);
@@ -332,7 +322,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*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) ;
LLViewerTexture *getTEImage(const U8 te) const;
void fitFaceTexture(const U8 face);
@@ -432,12 +422,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 +461,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 +508,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);
@@ -589,15 +594,20 @@ 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;
// 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;
@@ -684,6 +694,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 +724,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;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 54ccfb9aae..3eeab0bf3e 100644
--- 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"
@@ -78,11 +80,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;
@@ -386,9 +386,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
}
else if (compressed)
{
- U8 compbuffer[2048];
S32 uncompressed_length = 2048;
- S32 compressed_length;
compressed_dp.reset();
U32 flags = 0;
@@ -397,24 +395,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?
{
@@ -926,26 +909,33 @@ 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)
{
- idle_list.push_back( 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
@@ -955,10 +945,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())
@@ -970,27 +963,23 @@ 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++;
- }
- }
- for (std::vector<LLViewerObject*>::iterator kill_iter = kill_list.begin();
- kill_iter != kill_list.end(); kill_iter++)
- {
- objectp = *kill_iter;
- killObject(objectp);
+ llassert(objectp->isActive());
+ objectp->idleUpdate(agent, world, frame_time);
+
}
+
+ //update flexible objects
+ LLVolumeImplFlexible::updateClass();
+
+ //update animated textures
+ LLViewerTextureAnim::updateClass();
}
+
+
fetchObjectCosts();
fetchPhysicsFlags();
@@ -1057,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);
}
@@ -1078,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();
@@ -1096,7 +1083,7 @@ void LLViewerObjectList::fetchObjectCosts()
mStaleObjectCost.erase(iter++);
- if (count++ >= 450)
+ if (object_index >= MAX_CONCURRENT_PHYSICS_REQUESTS)
{
break;
}
@@ -1141,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.
@@ -1151,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 )
{
@@ -1218,7 +1207,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())
@@ -1395,6 +1384,27 @@ 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);
@@ -1409,16 +1419,38 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
if (active)
{
//llinfos << "Adding " << objectp->mID << " " << objectp->getPCodeString() << " to active list." << llendl;
- mActiveObjects.insert(objectp);
- objectp->setOnActiveList(TRUE);
+ 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)
@@ -1489,6 +1521,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...
@@ -1500,6 +1536,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)
{
@@ -1516,8 +1554,15 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
}
}
- gPipeline.shiftObjects(offset);
- LLWorld::getInstance()->shiftRegions(offset);
+ {
+ LLFastTimer t(FTM_PIPELINE_SHIFT);
+ gPipeline.shiftObjects(offset);
+ }
+
+ {
+ LLFastTimer t(FTM_REGION_SHIFT);
+ LLWorld::getInstance()->shiftRegions(offset);
+ }
}
void LLViewerObjectList::repartitionObjects()
@@ -1721,7 +1766,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)
{
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 64925f46ae..449a4633ff 100644
--- 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);
@@ -197,7 +200,7 @@ protected:
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/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 9db784101d..77e382b8c7 100644
--- 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);
@@ -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;
@@ -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
--- 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/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6b3e04348a..345023dbfa 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -476,7 +476,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;
}
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 3e20f999c0..c9959c63ec 100644
--- 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);
///////////////////
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e3cb985ddb..b607afbd9d 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -255,10 +255,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:
@@ -655,6 +654,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'
@@ -1151,6 +1175,7 @@ void LLViewerRegion::getInfo(LLSD& info)
void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
{
sim_features = mSimulatorFeatures;
+
}
void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
@@ -1461,7 +1486,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
{
@@ -1489,17 +1515,17 @@ 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("DispatchRegionInfo");
+ capabilityNames.append("EnvironmentSettings");
capabilityNames.append("EstateChangeInfo");
capabilityNames.append("EventQueueGet");
- capabilityNames.append("EnvironmentSettings");
- capabilityNames.append("ObjectMedia");
- capabilityNames.append("ObjectMediaNavigate");
if (gSavedSettings.getBOOL("UseHTTPInventory"))
{
@@ -1510,52 +1536,56 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
}
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("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("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("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");
capabilityNames.append("ViewerStartAuction");
capabilityNames.append("ViewerStats");
-
+
// Please add new capabilities alphabetically to reduce
// merge conflicts.
}
@@ -1794,7 +1824,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");
@@ -1827,4 +1860,9 @@ bool LLViewerRegion::meshRezEnabled() const
mSimulatorFeatures["MeshRezEnabled"].asBoolean());
}
+bool LLViewerRegion::dynamicPathfindingEnabled() const
+{
+ return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") &&
+ mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean());
+}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c483c6ef52..c9fffaf30e 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -202,6 +202,7 @@ public:
// 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);
@@ -285,6 +286,9 @@ public:
void getSimulatorFeatures(LLSD& info);
void setSimulatorFeatures(const LLSD& info);
+
+ bool dynamicPathfindingEnabled() const;
+
typedef enum
{
CACHE_MISS_TYPE_FULL = 0,
@@ -325,6 +329,7 @@ public:
bool objectsCrossParcel(const std::vector<LLBBox>& boxes) const;
void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
+ void getNeighboringRegionsStatus( std::vector<S32>& regions );
public:
struct CompareDistance
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 10c61c01d5..4b0e0598f6 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -63,8 +63,16 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
+//transform shaders
+LLGLSLShader gTransformPositionProgram;
+LLGLSLShader gTransformTexCoordProgram;
+LLGLSLShader gTransformNormalProgram;
+LLGLSLShader gTransformColorProgram;
+LLGLSLShader gTransformBinormalProgram;
+
//utility shaders
LLGLSLShader gOcclusionProgram;
+LLGLSLShader gOcclusionCubeProgram;
LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
LLGLSLShader gSplatTextureRectProgram;
@@ -72,6 +80,7 @@ LLGLSLShader gGlowCombineFXAAProgram;
LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
+LLGLSLShader gClipProgram;
LLGLSLShader gAlphaMaskProgram;
//object shaders
@@ -134,6 +143,8 @@ LLGLSLShader gUnderWaterProgram;
//interface shaders
LLGLSLShader gHighlightProgram;
+LLGLSLShader gPathfindingProgram;
+LLGLSLShader gPathfindingNoNormalsProgram;
//avatar shader handles
LLGLSLShader gAvatarProgram;
@@ -178,6 +189,7 @@ LLGLSLShader gDeferredSunProgram;
LLGLSLShader gDeferredBlurLightProgram;
LLGLSLShader gDeferredSoftenProgram;
LLGLSLShader gDeferredShadowProgram;
+LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAttachmentShadowProgram;
@@ -437,7 +449,8 @@ void LLViewerShaderMgr::setShaders()
S32 wl_class = 2;
S32 water_class = 2;
S32 deferred_class = 0;
-
+ S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
+
if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
gSavedSettings.getBOOL("RenderDeferred") &&
gSavedSettings.getBOOL("RenderAvatarVP") &&
@@ -475,6 +488,7 @@ void LLViewerShaderMgr::setShaders()
gSky.mVOSkyp->forceSkyUpdate();
}
+
// Load lighting shaders
mVertexShaderLevel[SHADER_LIGHTING] = light_class;
mVertexShaderLevel[SHADER_INTERFACE] = light_class;
@@ -484,6 +498,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 +508,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();
+
+ if (loaded)
+ {
+ loaded = loadShadersWater();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersWindLight();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersEffects();
+ }
+
+ if (loaded)
+ {
+ loaded = loadShadersInterface();
+ }
+
+ if (loaded)
+
+ {
+ loaded = loadTransformShaders();
+ }
- // Set the actual level
- mVertexShaderLevel[SHADER_AVATAR] = avatar_class;
- loadShadersAvatar();
- if (mVertexShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if (mVertexShaderLevel[SHADER_AVATAR] == 0)
+ 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 +660,13 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
gOcclusionProgram.unload();
+ gOcclusionCubeProgram.unload();
gDebugProgram.unload();
+ gClipProgram.unload();
gAlphaMaskProgram.unload();
gUIProgram.unload();
+ gPathfindingProgram.unload();
+ gPathfindingNoNormalsProgram.unload();
gCustomAlphaProgram.unload();
gGlowCombineProgram.unload();
gSplatTextureRectProgram.unload();
@@ -692,6 +756,12 @@ void LLViewerShaderMgr::unloadShaders()
gDeferredSkinnedBumpProgram.unload();
gDeferredSkinnedAlphaProgram.unload();
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformBinormalProgram.unload();
+
mVertexShaderLevel[SHADER_LIGHTING] = 0;
mVertexShaderLevel[SHADER_OBJECT] = 0;
mVertexShaderLevel[SHADER_AVATAR] = 0;
@@ -700,6 +770,7 @@ void LLViewerShaderMgr::unloadShaders()
mVertexShaderLevel[SHADER_INTERFACE] = 0;
mVertexShaderLevel[SHADER_EFFECT] = 0;
mVertexShaderLevel[SHADER_WINDLIGHT] = 0;
+ mVertexShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mVertexShadersLoaded = 0;
}
@@ -828,7 +899,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment()
if (mVertexShaderLevel[SHADER_ENVIRONMENT] == 0)
{
gTerrainProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -868,7 +939,7 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gWaterProgram.unload();
gUnderWaterProgram.unload();
gTerrainWaterProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -953,7 +1024,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gGlowExtractProgram.unload();
gPostColorFilterProgram.unload();
gPostNightVisionProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -1013,6 +1084,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.unload();
gDeferredSoftenProgram.unload();
gDeferredShadowProgram.unload();
+ gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
gDeferredAttachmentShadowProgram.unload();
@@ -1200,7 +1272,7 @@ 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,7 +1281,7 @@ 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);
@@ -1368,6 +1440,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
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.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();
@@ -2410,7 +2492,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarWaterProgram.unload();
gAvatarEyeballProgram.unload();
gAvatarPickProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2504,7 +2586,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (mVertexShaderLevel[SHADER_INTERFACE] == 0)
{
gHighlightProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2529,6 +2611,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));
@@ -2647,6 +2749,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 +2769,16 @@ 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)
+ {
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
@@ -2682,7 +2804,7 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
{
gWLSkyProgram.unload();
gWLCloudProgram.unload();
- return FALSE;
+ return TRUE;
}
if (success)
@@ -2712,6 +2834,95 @@ BOOL LLViewerShaderMgr::loadShadersWindLight()
return success;
}
+BOOL LLViewerShaderMgr::loadTransformShaders()
+{
+ BOOL success = TRUE;
+
+ if (mVertexShaderLevel[SHADER_TRANSFORM] < 1)
+ {
+ gTransformPositionProgram.unload();
+ gTransformTexCoordProgram.unload();
+ gTransformNormalProgram.unload();
+ gTransformColorProgram.unload();
+ gTransformBinormalProgram.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)
+ {
+ gTransformBinormalProgram.mName = "Binormal Transform Shader";
+ gTransformBinormalProgram.mShaderFiles.clear();
+ gTransformBinormalProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
+ gTransformBinormalProgram.mShaderLevel = mVertexShaderLevel[SHADER_TRANSFORM];
+
+ const char* varyings[] = {
+ "binormal_out",
+ };
+
+ success = gTransformBinormalProgram.createShader(NULL, NULL, 1, varyings);
+ }
+
+
+ return success;
+}
+
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index 95eb551bf1..d6dd645e8c 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -54,6 +54,7 @@ public:
BOOL loadShadersWater();
BOOL loadShadersInterface();
BOOL loadShadersWindLight();
+ BOOL loadTransformShaders();
std::vector<S32> mVertexShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -69,6 +70,7 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
+ SHADER_TRANSFORM,
SHADER_COUNT
};
@@ -209,13 +211,24 @@ 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 gTransformBinormalProgram;
+
+
+
//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 gClipProgram;
extern LLGLSLShader gAlphaMaskProgram;
//output tex0[tc0] + tex1[tc1]
@@ -288,6 +301,8 @@ extern LLGLSLShader gGlowExtractProgram;
//interface shaders
extern LLGLSLShader gHighlightProgram;
+extern LLGLSLShader gPathfindingProgram;
+extern LLGLSLShader gPathfindingNoNormalsProgram;
// avatar shader handles
extern LLGLSLShader gAvatarProgram;
@@ -328,6 +343,7 @@ extern LLGLSLShader gDeferredBlurLightProgram;
extern LLGLSLShader gDeferredAvatarProgram;
extern LLGLSLShader gDeferredSoftenProgram;
extern LLGLSLShader gDeferredShadowProgram;
+extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 497e95c5e3..603634e5f3 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"),
@@ -783,12 +787,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"];
@@ -927,15 +960,8 @@ LLSD LLViewerStats::PhaseMap::dumpPhases()
for (phase_map_t::iterator iter = mPhaseMap.begin(); iter != mPhaseMap.end(); ++iter)
{
const std::string& phase_name = iter->first;
- result[phase_name]["completed"] = !(iter->second.getStarted());
+ result[phase_name]["completed"] = LLSD::Integer(!(iter->second.getStarted()));
result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32();
-#if 0 // global stats for each phase seem like overkill here
- phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name);
- if (stats_iter != sPhaseStats.end())
- {
- result[phase_name]["stats"] = stats_iter->second.getData();
- }
-#endif
}
return result;
}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 750d963f69..554e4d647e 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -71,6 +71,10 @@ public:
LLStat mSimSimPhysicsShapeUpdateMsec;
LLStat mSimSimPhysicsOtherMsec;
+ LLStat mSimSimAIStepMsec;
+ LLStat mSimSimSkippedSilhouetteSteps;
+ LLStat mSimSimPctSteppedCharacters;
+
LLStat mSimAgentMsec;
LLStat mSimImagesMsec;
LLStat mSimScriptMsec;
@@ -83,6 +87,7 @@ public:
LLStat mSimObjects;
LLStat mSimActiveObjects;
LLStat mSimActiveScripts;
+ LLStat mSimPctScriptsRun;
LLStat mSimInPPS;
LLStat mSimOutPPS;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d844aeb12a..96d7890a9e 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -62,6 +62,7 @@
#include "llmediaentry.h"
#include "llvovolume.h"
#include "llviewermedia.h"
+#include "lltexturecache.h"
///////////////////////////////////////////////////////////////////////////////
// statics
@@ -409,7 +410,11 @@ void LLViewerTextureManager::cleanup()
void LLViewerTexture::initClass()
{
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
- sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
+
+ if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
+ {
+ sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
+ }
}
// static
@@ -619,6 +624,7 @@ LLViewerTexture::~LLViewerTexture()
void LLViewerTexture::init(bool firstinit)
{
mBoostLevel = LLViewerTexture::BOOST_NONE;
+ mSelectedTime = 0.f;
mFullWidth = 0;
mFullHeight = 0;
@@ -674,11 +680,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 (mBoostLevel == LLViewerTexture::BOOST_SELECTED)
+ {
+ mSelectedTime = gFrameTimeSeconds;
+ }
+
}
@@ -1236,7 +1249,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mIsMissingAsset = FALSE;
mLoadedCallbackDesiredDiscardLevel = S8_MAX;
- mPauseLoadedCallBacks = TRUE ;
+ mPauseLoadedCallBacks = FALSE ;
mNeedsCreateTexture = FALSE;
@@ -1253,6 +1266,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
mRequestDeltaTime = 0.f;
mForSculpt = FALSE ;
mIsFetched = FALSE ;
+ mInFastCacheList = FALSE;
mCachedRawImage = NULL ;
mCachedRawDiscardLevel = -1 ;
@@ -1266,6 +1280,8 @@ void LLViewerFetchedTexture::init(bool firstinit)
mLastReferencedSavedRawImageTime = 0.0f ;
mKeptSavedRawImageTime = 0.f ;
mLastCallBackActiveTime = 0.f;
+
+ mInDebug = FALSE;
}
LLViewerFetchedTexture::~LLViewerFetchedTexture()
@@ -1310,14 +1326,47 @@ void LLViewerFetchedTexture::cleanup()
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();
+ setIsMissingAsset();
+ mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
+ }
+ else
+ {
+ mRequestedDiscardLevel = mDesiredDiscardLevel + 1;
+ mIsRawImageValid = TRUE;
+ addToCreateTexture() ;
+ }
+ }
+}
+
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) ;
@@ -1398,10 +1447,10 @@ void LLViewerFetchedTexture::dump()
// ONLY called from LLViewerFetchedTextureList
void LLViewerFetchedTexture::destroyTexture()
{
- if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
- {
- return ;
- }
+ //if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
+ //{
+ // return ;
+ //}
if (mNeedsCreateTexture)//return if in the process of generating a new texture.
{
return ;
@@ -1735,7 +1784,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))
{
@@ -1836,8 +1885,6 @@ F32 LLViewerFetchedTexture::maxDecodePriority()
void LLViewerFetchedTexture::setDecodePriority(F32 priority)
{
- llassert(!mInImageList);
-
mDecodePriority = priority;
if(mDecodePriority < F_ALMOST_ZERO)
@@ -1865,13 +1912,34 @@ void LLViewerFetchedTexture::updateVirtualSize()
for(U32 i = 0 ; i < mNumFaces ; i++)
{
LLFace* facep = mFaceList[i] ;
- if(facep->getDrawable()->isRecentlyVisible())
+ if( facep )
{
- addTextureStats(facep->getVirtualSize()) ;
- setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
+ 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)
{
mMaxVirtualSizeResetCounter--;
@@ -1898,6 +1966,20 @@ 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");
@@ -1935,6 +2017,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();
@@ -2052,6 +2138,10 @@ bool LLViewerFetchedTexture::updateFetch()
{
make_request = false;
}
+ else if(mDesiredDiscardLevel > getMaxDiscardLevel())
+ {
+ make_request = false;
+ }
else if (mNeedsCreateTexture || mIsMissingAsset)
{
make_request = false;
@@ -2060,6 +2150,11 @@ 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;
@@ -2152,7 +2247,10 @@ bool LLViewerFetchedTexture::updateFetch()
void LLViewerFetchedTexture::clearFetchedResults()
{
- llassert_always(!mNeedsCreateTexture && !mIsFetching);
+ if(mNeedsCreateTexture || mIsFetching)
+ {
+ return ;
+ }
cleanup();
destroyGLTexture();
@@ -2167,11 +2265,13 @@ void LLViewerFetchedTexture::forceToDeleteRequest()
{
if (mHasFetcher)
{
- LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
mHasFetcher = FALSE;
mIsFetching = FALSE ;
- resetTextureStats();
}
+
+ resetTextureStats();
+
+ mDesiredDiscardLevel = getMaxDiscardLevel() + 1;
}
void LLViewerFetchedTexture::setIsMissingAsset()
@@ -2182,7 +2282,8 @@ void LLViewerFetchedTexture::setIsMissingAsset()
}
else
{
- llwarns << mUrl << ": Marking image as missing" << llendl;
+ //it is normal no map tile on an empty region.
+ //llwarns << mUrl << ": Marking image as missing" << llendl;
}
if (mHasFetcher)
{
@@ -2214,10 +2315,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);
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index f1105c3705..2e7949e9a3 100644..100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -275,6 +275,7 @@ private:
protected:
LLUUID mID;
S32 mBoostLevel; // enum describing priority level
+ F32 mSelectedTime; // time texture was last selected
S32 mFullWidth;
S32 mFullHeight;
BOOL mUseMipMaps ;
@@ -436,6 +437,8 @@ 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.
@@ -498,6 +501,9 @@ public:
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() ;
@@ -516,6 +522,8 @@ private:
private:
BOOL mFullyLoaded;
+ BOOL mInDebug;
+ BOOL mInFastCacheList;
protected:
std::string mLocalFileName;
diff --git a/indra/newview/llviewertextureanim.cpp b/indra/newview/llviewertextureanim.cpp
index 9f1ac7c49c..2b364851a7 100644
--- 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
--- 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 528e0080b7..49d7e8b842 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -58,7 +58,7 @@
#include "pipeline.h"
#include "llappviewer.h"
#include "llxuiparser.h"
-#include "llagent.h"
+#include "llviewerdisplay.h"
////////////////////////////////////////////////////////////////////////////
@@ -276,6 +276,7 @@ void LLViewerTextureList::shutdown()
// Flush all of the references
mLoadingStreamList.clear();
mCreateTextureList.clear();
+ mFastCacheList.clear();
mUUIDMap.clear();
@@ -453,6 +454,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
LLGLenum primary_format,
LLHost request_from_host)
{
+ static LLCachedControl<bool> fast_cache_fetching_enabled(gSavedSettings, "FastCacheFetchEnabled");
+
LLPointer<LLViewerFetchedTexture> imagep ;
switch(texture_type)
{
@@ -490,6 +493,11 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
imagep->forceActive() ;
}
+ if(fast_cache_fetching_enabled)
+ {
+ mFastCacheList.insert(imagep);
+ imagep->setInFastCacheList(true);
+ }
return imagep ;
}
@@ -503,6 +511,7 @@ LLViewerFetchedTexture *LLViewerTextureList::findImage(const LLUUID &image_id)
void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (image->isInImageList())
@@ -519,6 +528,7 @@ void LLViewerTextureList::addImageToList(LLViewerFetchedTexture *image)
void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
{
+ assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
if (!image->isInImageList())
@@ -593,16 +603,24 @@ 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)
{
- if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ static BOOL cleared = FALSE;
+ if(gTeleportDisplay)
{
- clearFetchingRequests();
+ if(!cleared)
+ {
+ clearFetchingRequests();
+ gPipeline.clearRebuildGroups();
+ cleared = TRUE;
+ }
return;
}
+ cleared = FALSE;
LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec());
@@ -613,6 +631,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);
@@ -673,14 +696,13 @@ void LLViewerTextureList::clearFetchingRequests()
return;
}
+ LLAppViewer::getTextureFetch()->deleteAllRequests();
+
for (image_priority_list_t::iterator iter = mImageList.begin();
iter != mImageList.end(); ++iter)
{
- LLViewerFetchedTexture* image = *iter;
- if(image->hasFetcher())
- {
- image->forceToDeleteRequest() ;
- }
+ LLViewerFetchedTexture* imagep = *iter;
+ imagep->forceToDeleteRequest() ;
}
}
@@ -688,10 +710,11 @@ 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())
{
@@ -699,13 +722,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();
@@ -754,7 +783,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);
@@ -764,15 +802,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)
{
@@ -827,6 +885,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)
@@ -850,15 +938,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)
{
@@ -868,43 +965,46 @@ 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)
//{
@@ -936,6 +1036,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();
@@ -1583,49 +1686,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 e89997fe28..3dda973d3f 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -111,6 +111,7 @@ public:
void doPrefetchImages();
void clearFetchingRequests();
+ void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
static S32 getMinVideoRamSetting();
static S32 getMaxVideoRamSetting(bool get_recommended = false);
@@ -120,6 +121,7 @@ private:
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);
@@ -173,6 +175,7 @@ public:
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;
diff --git a/indra/newview/llviewervisualparam.h b/indra/newview/llviewervisualparam.h
index dd7751acd7..3bc95cbfbf 100644
--- a/indra/newview/llviewervisualparam.h
+++ b/indra/newview/llviewervisualparam.h
@@ -83,11 +83,11 @@ public:
// New Virtual functions
virtual F32 getTotalDistortion() = 0;
- virtual const LLVector3& getAvgDistortion() = 0;
+ virtual const LLVector4a& 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;
+ 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; }
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 39e330ad66..1def2db829 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -122,6 +122,7 @@
#include "llkeyboard.h"
#include "lllineeditor.h"
#include "llmenugl.h"
+#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmodaldialog.h"
#include "llmorphview.h"
#include "llmoveview.h"
@@ -175,6 +176,7 @@
#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
+#include "llvopartgroup.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
@@ -561,6 +563,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;
@@ -613,7 +618,7 @@ public:
addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
LLMeshRepository::sHTTPRetryCount));
ypos += y_inc;
-
+
addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing));
ypos += y_inc;
@@ -1553,8 +1558,12 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
- LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
- llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
+ 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";
@@ -1683,8 +1692,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;
@@ -1704,9 +1712,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);
@@ -1923,10 +1928,14 @@ 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
@@ -1973,12 +1982,12 @@ void LLViewerWindow::shutdownViews()
gMorphView->setVisible(FALSE);
}
llinfos << "Global views cleaned." << llendl ;
-
+
// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
// will crump with LL_ERRS.
LLModalDialog::shutdownModals();
llinfos << "LLModalDialog shut down." << llendl;
-
+
// destroy the nav bar, not currently part of gViewerWindow
// *TODO: Make LLNavigationBar part of gViewerWindow
if (LLNavigationBar::instanceExists())
@@ -1986,17 +1995,19 @@ void LLViewerWindow::shutdownViews()
delete LLNavigationBar::getInstance();
}
llinfos << "LLNavigationBar destroyed." << llendl ;
-
+
// destroy menus after instantiating navbar above, as it needs
// access to gMenuHolder
cleanup_menus();
llinfos << "menus destroyed." << llendl ;
-
+
// Delete all child views.
delete mRootView;
mRootView = NULL;
llinfos << "RootView deleted." << llendl ;
-
+
+ LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit();
+
// Automatically deleted as children of mRootView. Fix the globals.
gStatusBar = NULL;
gIMMgr = NULL;
@@ -3168,8 +3179,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)
@@ -3523,8 +3533,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;
@@ -4224,14 +4237,48 @@ 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 > 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);
+ 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)
@@ -4420,11 +4467,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
gPipeline.resetDrawOrders();
}
+ if (reset_deferred)
+ {
+ mWorldViewRectRaw = window_rect;
+ scratch_space.flush();
+ scratch_space.release();
+ gPipeline.allocateScreenBuffer(original_width, original_height);
+
+ }
+
if (high_res)
{
send_agent_resume();
}
-
+
return ret;
}
@@ -4660,6 +4716,8 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLVOAvatar::destroyGL();
stop_glerror();
+ LLVOPartGroup::destroyGL();
+
LLViewerDynamicTexture::destroyGL();
stop_glerror();
@@ -4713,7 +4771,8 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gBumpImageList.restoreGL();
LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
-
+ LLVOPartGroup::restoreGL();
+
gResizeScreenTexture = TRUE;
gWindowResized = TRUE;
@@ -4748,8 +4807,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();
}
@@ -4759,8 +4817,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();
@@ -5196,8 +5257,10 @@ void LLPickInfo::getSurfaceInfo()
if (objectp->mDrawable.notNull() && mObjectFace > -1)
{
LLFace* facep = objectp->mDrawable->getFace(mObjectFace);
-
- mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ if (facep)
+ {
+ mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal);
+ }
}
// and XY coords:
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index eada77156e..627238b0f5 100644..100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -817,6 +817,7 @@ LLVOAvatar::~LLVOAvatar()
lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
mRoot.removeAllChildren();
+ mJointMap.clear();
deleteAndClearArray(mSkeleton);
deleteAndClearArray(mCollisionVolumes);
@@ -961,7 +962,7 @@ void LLVOAvatar::deleteLayerSetCaches(bool clearAll)
}
if (mBakedTextureDatas[i].mMaskTexName)
{
- glDeleteTextures(1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (GLuint*)&(mBakedTextureDatas[i].mMaskTexName));
mBakedTextureDatas[i].mMaskTexName = 0 ;
}
}
@@ -1459,8 +1460,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)
@@ -1934,6 +1933,7 @@ void LLVOAvatar::buildCharacter()
// remove all of mRoot's children
//-------------------------------------------------------------------------
mRoot.removeAllChildren();
+ mJointMap.clear();
mIsBuilt = FALSE;
//-------------------------------------------------------------------------
@@ -2094,11 +2094,17 @@ void LLVOAvatar::releaseMeshData()
if (mDrawable.notNull())
{
LLFace* facep = mDrawable->getFace(0);
- facep->setSize(0, 0);
- for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+ if (facep)
{
- facep = mDrawable->getFace(i);
facep->setSize(0, 0);
+ for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+ {
+ facep = mDrawable->getFace(i);
+ if (facep)
+ {
+ facep->setSize(0, 0);
+ }
+ }
}
}
@@ -2183,15 +2189,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);
@@ -2379,7 +2390,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
}
}
-static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Update Avatar");
+static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");
static LLFastTimer::DeclareTimer FTM_JOINT_UPDATE("Update Joints");
//------------------------------------------------------------------------
@@ -2412,7 +2423,7 @@ 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);
@@ -2420,12 +2431,12 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
if (isDead())
{
llinfos << "Warning! Idle on dead avatar" << llendl;
- return TRUE;
+ return;
}
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
{
- return TRUE;
+ return;
}
checkTextureLoading() ;
@@ -2508,8 +2519,6 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
idleUpdateNameTag( root_pos_last );
idleUpdateRenderCost();
-
- return TRUE;
}
void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
@@ -2681,7 +2690,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
if (isImpostor() && !mNeedsImpostorUpdate)
{
- LLVector4a ext[2];
+ LL_ALIGN_16(LLVector4a ext[2]);
F32 distance;
LLVector3 angle;
@@ -4236,10 +4245,14 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
mNeedsSkin = FALSE;
mLastSkinTime = gFrameTimeSeconds;
- LLVertexBuffer* vb = mDrawable->getFace(0)->getVertexBuffer();
- if (vb)
+ LLFace * face = mDrawable->getFace(0);
+ if (face)
{
- vb->flush();
+ LLVertexBuffer* vb = face->getVertexBuffer();
+ if (vb)
+ {
+ vb->flush();
+ }
}
}
}
@@ -4408,7 +4421,9 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
}
// 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);
first_pass = FALSE;
@@ -4552,7 +4567,20 @@ void LLVOAvatar::updateTextures()
LLWearableType::EType wearable_type = LLVOAvatarDictionary::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++)
{
@@ -5122,7 +5150,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;
}
@@ -6650,7 +6691,7 @@ void LLVOAvatar::updateMeshTextures()
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
- paused = mLoadedCallbacksPaused ;
+ paused = !isVisible();
}
std::vector<BOOL> is_layer_baked;
@@ -7195,7 +7236,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
if(!isSelf())
{
src_callback_list = &mCallbackTextureList ;
- paused = mLoadedCallbacksPaused ;
+ paused = !isVisible();
}
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
@@ -7492,7 +7533,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
}
U32 gl_name;
- LLImageGL::generateTextures(1, &gl_name );
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_ALPHA8, 1, &gl_name );
stop_glerror();
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, gl_name);
@@ -7529,7 +7570,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
maskData->mLastDiscardLevel = discard_level;
if (self->mBakedTextureDatas[baked_index].mMaskTexName)
{
- LLImageGL::deleteTextures(1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, &(self->mBakedTextureDatas[baked_index].mMaskTexName));
}
self->mBakedTextureDatas[baked_index].mMaskTexName = gl_name;
found_texture_id = true;
@@ -8395,7 +8436,7 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (!facep->getVertexBuffer())
+ if (!facep || !facep->getVertexBuffer())
{
dirtyMesh(2);
}
@@ -8679,6 +8720,12 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index
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);
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6fb56a4c0b..1adb680962 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -93,6 +93,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.
@@ -124,7 +134,7 @@ public:
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);
virtual BOOL updateLOD();
BOOL updateJointLODs();
void updateLODRiggedAttachments( void );
@@ -215,7 +225,7 @@ public:
bool isBuilt() const { return mIsBuilt; }
private: //aligned members
- LLVector4a mImpostorExtents[2];
+ LL_ALIGN_16(LLVector4a mImpostorExtents[2]);
private:
BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
@@ -356,6 +366,10 @@ public:
LLVector3 mHeadOffset; // current head position
LLViewerJoint mRoot;
+
+ typedef std::map<std::string, LLJoint*> joint_map_t;
+ joint_map_t mJointMap;
+
protected:
static BOOL parseSkeletonFile(const std::string& filename);
void buildCharacter();
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index d2609e5587..7a81063f83 100644..100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -668,15 +668,13 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
}
// virtual
-BOOL LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
+void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
{
- if (!isAgentAvatarValid())
+ if (isAgentAvatarValid())
{
- return TRUE;
+ LLVOAvatar::idleUpdate(agent, world, time);
+ idleUpdateTractorBeam();
}
- LLVOAvatar::idleUpdate(agent, world, time);
- idleUpdateTractorBeam();
- return TRUE;
}
// virtual
@@ -795,7 +793,7 @@ 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);
}
}
@@ -2132,9 +2130,7 @@ LLSD LLVOAvatarSelf::metricsData()
{
// runway - add region info
LLSD result;
- result["id"] = getID();
result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
- result["is_self"] = isSelf();
std::vector<S32> rez_counts;
LLVOAvatar::getNearbyRezzedStats(rez_counts);
result["nearby"] = LLSD::emptyMap();
@@ -2148,7 +2144,6 @@ LLSD LLVOAvatarSelf::metricsData()
result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
result["timers"]["invisible"] = mInvisibleTimer.getElapsedTimeF32();
result["timers"]["fully_loaded"] = mFullyLoadedTimer.getElapsedTimeF32();
- result["phases"] = getPhases().dumpPhases();
result["startup"] = LLStartUp::getPhases().dumpPhases();
return result;
@@ -2157,7 +2152,12 @@ LLSD LLVOAvatarSelf::metricsData()
class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
{
public:
- ViewerAppearanceChangeMetricsResponder()
+ ViewerAppearanceChangeMetricsResponder( S32 expected_sequence,
+ volatile const S32 & live_sequence,
+ volatile bool & reporting_started):
+ mExpectedSequence(expected_sequence),
+ mLiveSequence(live_sequence),
+ mReportingStarted(reporting_started)
{
}
@@ -2176,14 +2176,44 @@ public:
error(status,reason);
}
}
+
+ // virtual
+ void error(U32 status_num, const std::string & reason)
+ {
+ }
+
+ // virtual
+ void result(const LLSD & content)
+ {
+ if (mLiveSequence == mExpectedSequence)
+ {
+ mReportingStarted = true;
+ }
+ }
+
+private:
+ S32 mExpectedSequence;
+ volatile const S32 & mLiveSequence;
+ volatile bool & mReportingStarted;
};
void LLVOAvatarSelf::sendAppearanceChangeMetrics()
{
// 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;
+
+ // 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;
@@ -2196,8 +2226,10 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()
{
LLCurlRequest::headers_t headers;
LLHTTPClient::post(caps_url,
- msg,
- new ViewerAppearanceChangeMetricsResponder);
+ msg,
+ new ViewerAppearanceChangeMetricsResponder(report_sequence,
+ report_sequence,
+ reporting_started));
}
}
@@ -2751,7 +2783,7 @@ void LLVOAvatarSelf::deleteScratchTextures()
namep;
namep = sScratchTexNames.getNextData() )
{
- LLImageGL::deleteTextures(1, (U32 *)namep );
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, 0, -1, 1, (U32 *)namep );
stop_glerror();
}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 543891ca63..7bd0c0bf93 100644
--- 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();
@@ -75,7 +85,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
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8a79d564d3..566c33c0af 100644
--- 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"
@@ -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();
@@ -486,6 +494,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 +604,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 +615,143 @@ 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)
+{
+ LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+ 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);
+ object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, 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)
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 00a59facf7..b9835b8802 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -73,7 +73,7 @@ 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,
S32 face = -1, // which face to check, -1 = ALL_SIDES
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
index 0060f81ab5..97b7418b40 100644
--- 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
--- 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/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 5c10a80b07..e4f9915e93 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -48,6 +48,120 @@ const F32 MAX_PART_LIFETIME = 120.f;
extern U64 gFrameTime;
+LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
+
+void LLVOPartGroup::initClass()
+{
+ for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+ {
+ sVBSlotFree[i] = i;
+ }
+
+ sVBSlotCursor = sVBSlotFree;
+}
+
+//static
+void LLVOPartGroup::restoreGL()
+{
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK, 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 >= sVBSlotFree+LL_MAX_PARTICLE_COUNT)
+ { //no more available slots
+ return -1;
+ }
+
+ S32 ret = *sVBSlotCursor;
+ sVBSlotCursor++;
+
+ return ret;
+}
+
+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 true;
+}
+
+//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 +176,6 @@ LLVOPartGroup::~LLVOPartGroup()
{
}
-
BOOL LLVOPartGroup::isActive() const
{
return FALSE;
@@ -83,9 +196,8 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-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)
@@ -287,9 +399,6 @@ void LLVOPartGroup::getGeometry(S32 idx,
const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
- U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
-
-
LLVector4a part_pos_agent;
part_pos_agent.load3(part.mPosAgent.mV);
LLVector4a camera_agent;
@@ -361,33 +470,18 @@ void LLVOPartGroup::getGeometry(S32 idx,
verticesp->setAdd(ppamu, right);
(*verticesp++).getF32ptr()[3] = 0.f;
- //*verticesp++ = part_pos_agent + up - right;
- //*verticesp++ = part_pos_agent - up - right;
- //*verticesp++ = part_pos_agent + up + right;
- //*verticesp++ = part_pos_agent - up + right;
-
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
- *texcoordsp++ = LLVector2(0.f, 1.f);
- *texcoordsp++ = LLVector2(0.f, 0.f);
- *texcoordsp++ = LLVector2(1.f, 1.f);
- *texcoordsp++ = LLVector2(1.f, 0.f);
-
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
-
- *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
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ }
}
U32 LLVOPartGroup::getPartitionType() const
@@ -412,6 +506,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 +556,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 +568,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 +579,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 +594,13 @@ 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());
@@ -489,21 +620,45 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
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);
- 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;
+
+ object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx);
+ llassert(facep->getGeomCount() == 4);
+ llassert(facep->getIndicesCount() == 6);
+
+
vertex_count += facep->getGeomCount();
index_count += facep->getIndicesCount();
@@ -512,18 +667,31 @@ 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 &&
+ bool batched = false;
+
+ if (idx >= 0 &&
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);
+ if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mStart -= facep->getGeomCount();
+ draw_vec[idx]->mOffset = facep->getIndicesStart();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
}
- else
+
+
+ if (!batched)
{
U32 start = facep->getGeomIndex();
U32 end = start + facep->getGeomCount()-1;
@@ -541,7 +709,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
}
}
- buffer->flush();
mFaceList.clear();
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index e58fed86d9..42c1252d01 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -31,24 +31,39 @@
#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 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+ 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_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);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 312034022e..31358df85f 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -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
--- 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..cb905d02da 100644
--- 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)
@@ -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,
@@ -864,7 +868,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();
}
}
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 4564207da4..6687ce432f 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -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);
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 0554935539..52debc85ab 100644
--- 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);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 080d1f774a..538911e9b8 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -329,7 +329,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
- mTextureAnimp = new LLViewerTextureAnim();
+ mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@@ -431,7 +431,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
{
if (!mTextureAnimp)
{
- mTextureAnimp = new LLViewerTextureAnim();
+ mTextureAnimp = new LLViewerTextureAnim(this);
}
else
{
@@ -499,191 +499,168 @@ 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;
+ mFaceMappingChanged = TRUE;
+ gPipeline.markTextured(mDrawable);
}
-
- if (!(result & LLViewerTextureAnim::ROTATE))
+ mTexAnimMode = result | mTextureAnimp->mMode;
+
+ S32 start=0, end=mDrawable->getNumFaces()-1;
+ if (mTextureAnimp->mFace >= 0 && mTextureAnimp->mFace <= end)
{
- te->getRotation(&rot);
+ start = end = mTextureAnimp->mFace;
}
- if (!(result & LLViewerTextureAnim::TRANSLATE))
- {
- te->getOffset(&off_s,&off_t);
- }
- if (!(result & LLViewerTextureAnim::SCALE))
+
+ for (S32 i = start; i <= end; i++)
{
- te->getScale(&scale_s, &scale_t);
- }
+ LLFace* facep = mDrawable->getFace(i);
+ if (!facep) continue;
+ if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
- if (!facep->mTextureMatrix)
- {
- facep->mTextureMatrix = new LLMatrix4();
- }
+ const LLTextureEntry* te = facep->getTextureEntry();
+
+ if (!te)
+ {
+ 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);
+ }
- LLMatrix4& tex_mat = *facep->mTextureMatrix;
- tex_mat.setIdentity();
- LLVector3 trans ;
+ if (!facep->mTextureMatrix)
+ {
+ facep->mTextureMatrix = new LLMatrix4();
+ }
+
+ LLMatrix4& tex_mat = *facep->mTextureMatrix;
+ tex_mat.setIdentity();
+ LLVector3 trans ;
- if(facep->isAtlasInUse())
- {
- //
- //if use atlas for animated texture
- //apply the following transform to the animation matrix.
- //
-
- F32 tcoord_xoffset = 0.f ;
- F32 tcoord_yoffset = 0.f ;
- F32 tcoord_xscale = 1.f ;
- F32 tcoord_yscale = 1.f ;
if(facep->isAtlasInUse())
{
- const LLVector2* tmp = facep->getTexCoordOffset() ;
- tcoord_xoffset = tmp->mV[0] ;
- tcoord_yoffset = tmp->mV[1] ;
+ //
+ //if use atlas for animated texture
+ //apply the following transform to the animation matrix.
+ //
+
+ F32 tcoord_xoffset = 0.f ;
+ F32 tcoord_yoffset = 0.f ;
+ F32 tcoord_xscale = 1.f ;
+ F32 tcoord_yscale = 1.f ;
+ if(facep->isAtlasInUse())
+ {
+ const LLVector2* tmp = facep->getTexCoordOffset() ;
+ tcoord_xoffset = tmp->mV[0] ;
+ tcoord_yoffset = tmp->mV[1] ;
- tmp = facep->getTexCoordScale() ;
- tcoord_xscale = tmp->mV[0] ;
- tcoord_yscale = tmp->mV[1] ;
- }
- trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f));
+ tmp = facep->getTexCoordScale() ;
+ tcoord_xscale = tmp->mV[0] ;
+ tcoord_yscale = tmp->mV[1] ;
+ }
+ 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
- {
- trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f));
- tex_mat.translate(LLVector3(-0.5f, -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
+ {
+ 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)
- {
- start = 0;
- count = getNumTEs();
- }
- else
+ if (mTexAnimMode && mTextureAnimp->mRate == 0)
{
- 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 +692,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 ;
}
@@ -743,6 +731,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 ||
@@ -833,7 +822,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 +878,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)
@@ -1062,9 +1050,33 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
+
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ 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->genBinormals(i);
+ LLFace::cacheFaceInVRAM(face);
+ }
+ }
+
+
return TRUE;
}
+
+
return FALSE;
}
@@ -1116,7 +1128,7 @@ 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();
@@ -1215,6 +1227,13 @@ 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();
}
@@ -1246,7 +1265,8 @@ 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));
@@ -1322,28 +1342,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,6 +1399,8 @@ 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));
facep->setViewerObject(this);
@@ -1416,14 +1437,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)
@@ -1459,7 +1483,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
updateRadius();
mDrawable->movePartition();
-
+
return res;
}
@@ -1471,11 +1495,11 @@ void LLVOVolume::preRebuild()
}
}
-void LLVOVolume::updateRelativeXform()
+void LLVOVolume::updateRelativeXform(bool force_identity)
{
if (mVolumeImpl)
{
- mVolumeImpl->updateRelativeXform();
+ mVolumeImpl->updateRelativeXform(force_identity);
return;
}
@@ -1495,15 +1519,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 +1629,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 +1646,8 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged )
{
+ dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+
compiled = TRUE;
if (mVolumeChanged)
@@ -1635,6 +1666,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 +1748,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 +1819,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);
@@ -1815,9 +1868,13 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
}
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)
@@ -2386,7 +2443,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()) ;
@@ -3098,6 +3160,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 +3432,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())
{
@@ -3450,9 +3514,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 +3537,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();
@@ -3512,7 +3583,6 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf())
{
updateRiggedVolume();
- genBBoxes(FALSE);
volume = mRiggedVolume;
transform = false;
}
@@ -3592,7 +3662,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e
{
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;
if (face_hitp != NULL)
@@ -3768,82 +3839,86 @@ 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);
+ LLMatrix4a bind_shape_matrix;
+ bind_shape_matrix.loadu(skin->mBindShapeMatrix);
+
+ LLVector4a* pos = dst_face.mPositions;
- for (U32 j = 0; j < dst_face.mNumVertices; ++j)
+ if( pos && weight && dst_face.mExtents )
{
- LLMatrix4a final_mat;
- final_mat.clear();
+ LLFastTimer t(FTM_SKIN_RIGGED);
- S32 idx[4];
+ for (U32 j = 0; j < dst_face.mNumVertices; ++j)
+ {
+ LLMatrix4a final_mat;
+ final_mat.clear();
- LLVector4 wght;
+ S32 idx[4];
- F32 scale = 0.f;
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = weight[j][k];
+ LLVector4 wght;
- idx[k] = (S32) floorf(w);
- wght[k] = w - floorf(w);
- scale += wght[k];
- }
+ F32 scale = 0.f;
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = weight[j][k];
- wght *= 1.f/scale;
+ idx[k] = (S32) floorf(w);
+ wght[k] = w - floorf(w);
+ scale += wght[k];
+ }
- for (U32 k = 0; k < 4; k++)
- {
- F32 w = wght[k];
+ wght *= 1.f/scale;
- LLMatrix4a src;
- src.setMul(mp[idx[k]], w);
+ for (U32 k = 0; k < 4; k++)
+ {
+ F32 w = wght[k];
- final_mat.add(src);
- }
+ LLMatrix4a src;
+ src.setMul(mp[idx[k]], 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);
+ }
}
}
}
@@ -3902,8 +3977,11 @@ 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)
{
+ LLFastTimer t(FTM_REGISTER_FACE);
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
@@ -3935,9 +4013,14 @@ 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->getRenderMatrix());
+ model_mat = &drawable->getWorldMatrix();
+ }
+ else if (drawable->isActive())
+ {
+ model_mat = &drawable->getRenderMatrix();
}
else
{
@@ -3948,6 +4031,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
+ //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;
LLViewerTexture* tex = facep->getTexture();
@@ -4041,8 +4126,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 +4159,8 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
+
+
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -4084,19 +4172,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();
@@ -4145,359 +4229,375 @@ 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)
+ {
+ ((LLDrawPoolAvatar*) old_pool)->removeRiggedFace(facep);
+ }
+
+ //add face to new pool
+ LLViewerTexture* tex = facep->getTexture();
+ U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ 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_ALPHA);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_ALPHA);
+ if (LLPipeline::sRenderDeferred)
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ }
+ else
+ {
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ }
}
}
- }
- else if (te->getShiny())
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY);
- }
else
{
- if (LLPipeline::sRenderDeferred)
+ if (te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
}
else
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SHINY);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
}
}
- }
- else
- {
- if (te->getFullbright())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_FULLBRIGHT);
- }
- else
+
+ if (te->getGlow())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_SIMPLE);
+ pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
}
- }
-
- if (te->getGlow())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_GLOW);
- }
- if (LLPipeline::sRenderDeferred)
- {
- if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
+ if (LLPipeline::sRenderDeferred)
{
- if (te->getBumpmap())
- {
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_BUMP);
- }
- else
+ if (type != LLDrawPool::POOL_ALPHA && !te->getFullbright())
{
- pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE);
+ 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
+ if (facep->canRenderAsMask())
+ { //can be treated as alpha mask
simple_faces.push_back(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);
+ }
+ alpha_faces.push_back(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 (te->getBumpmap())
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if (te->getShiny() || !te->getFullbright())
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(facep);
+ }
}
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ else
+ {
+ if (te->getBumpmap() && LLPipeline::sRenderBump)
+ { //needs normal + binormal
+ bump_faces.push_back(facep);
+ }
+ else if ((te->getShiny() && LLPipeline::sRenderBump) ||
+ !(te->getFullbright() || bake_sunlight))
+ { //needs normal
+ simple_faces.push_back(facep);
+ }
+ else
+ { //doesn't need normal
+ facep->setState(LLFace::FULLBRIGHT);
+ fullbright_faces.push_back(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)
+ {
+ drawablep->setState(LLDrawable::RIGGED);
+ }
+ else
+ {
+ drawablep->clearState(LLDrawable::RIGGED);
+ }
}
}
@@ -4539,7 +4639,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
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);
@@ -4564,31 +4664,35 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
-static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
{
- LLFastTimer tm(FTM_VOLUME_GEOM);
+ 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
+
S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
group->mBuilt = 1.f;
std::set<LLVertexBuffer*> mapped_buffers;
- 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)
{
@@ -4598,8 +4702,15 @@ 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 (!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())
{
@@ -4608,6 +4719,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
}
}
+
+ if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
+ {
+ vobj->updateRelativeXform();
+ }
+
drawablep->clearState(LLDrawable::REBUILD_ALL);
}
@@ -4630,16 +4747,19 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if(num_mapped_veretx_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();
+ }
}
}
}
@@ -4648,7 +4768,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
@@ -4674,8 +4794,20 @@ struct CompareBatchBreakerModified
}
};
+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, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures)
{
+ LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+
U32 buffer_usage = group->mBufferUsage;
#if LL_DARWIN
@@ -4693,15 +4825,18 @@ 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.begin(), faces.end(), CompareBatchBreakerModified());
+ }
+ else
+ {
+ //sort faces by distance
+ std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ }
}
bool hud_group = group->isHUDGroup() ;
@@ -4766,57 +4901,86 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
std::vector<LLViewerTexture*> texture_list;
- 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);
+ texture_list.push_back(tex);
+
+ //if (can_batch_texture(facep))
{
- facep = *i;
- if (facep->getTexture() != tex)
+ while (i != faces.end())
{
- 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 (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_list.size(); ++tex_idx)
{
- cur_tex = tex_idx;
- found = true;
- break;
+ if (facep->getTexture() == texture_list[tex_idx])
+ {
+ cur_tex = tex_idx;
+ found = true;
+ break;
+ }
}
- }
- if (!found)
+ if (!found)
+ {
+ cur_tex = texture_list.size();
+ }
+ }
+ else
{
- cur_tex = texture_list.size();
+ cur_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
- break;
+ 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
+ break;
+ }
+
+ if (cur_tex >= texture_index_channels)
+ { //cut batches when index channels are depleted
+ break;
+ }
+
+ tex = facep->getTexture();
+
+ texture_list.push_back(tex);
}
- if (cur_tex >= texture_index_channels)
- { //cut batches when index channels are depleted
+ if (geom_count + facep->getGeomCount() > max_vertices)
+ { //cut batches on geom count too big
break;
}
- tex = facep->getTexture();
+ ++i;
+ index_count += facep->getIndicesCount();
+ geom_count += facep->getGeomCount();
- texture_list.push_back(tex);
+ facep->setTextureIndex(cur_tex);
}
+ }
+
+ 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
@@ -4826,69 +4990,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
-
- facep->setTextureIndex(cur_tex);
}
}
-
- 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();
- }
- }
-
- //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();
@@ -4922,10 +5035,25 @@ 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);
+ }
}
}
@@ -5089,7 +5217,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;
@@ -5109,17 +5238,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)
- {
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
- llassert(facep->getIndicesCount() < 65536);
- //remember face (for sorting)
- mFaceList.push_back(facep);
- }
- else
+ if (facep)
{
- 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();
+ }
}
}
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 3cf434dc26..5482c80f2b 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -68,7 +68,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 +79,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 +114,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;
@@ -174,6 +173,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);
@@ -203,7 +203,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 +340,8 @@ public:
U8 mTexAnimMode;
private:
friend class LLDrawable;
-
+ friend class LLFace;
+
BOOL mFaceMappingChanged;
LLFrameTimer mTextureUpdateTimer;
S32 mLOD;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index cd78157944..e8a1c3d1d6 100644
--- 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
--- 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..a33f42cf84 100644
--- 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
diff --git a/indra/newview/llvowlsky.h b/indra/newview/llvowlsky.h
index 825e13a203..729dced15e 100644
--- 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/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index e386112334..4f52ff9778 100644
--- 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;
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index d2d48dc68f..83337b386d 100644
--- 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/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 2425b96678..be3e3ff30e 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -105,10 +105,16 @@ 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;
}
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 49d9d44d74..6077208799 100644
--- 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;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index b061c90d98..78ee3e4fd9 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -657,7 +657,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,6 +840,9 @@ 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;
for (x = min_x; x <= max_x; x += rwidth)
@@ -845,12 +851,12 @@ void LLWorld::updateWaterObjects()
{
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,
- 256.f+DEFAULT_WATER_HEIGHT));
+ 256.f + water_height));
waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
gPipeline.createObject(waterp);
mHoleWaterObjects.push_back(waterp);
@@ -907,7 +913,7 @@ void LLWorld::updateWaterObjects()
}
waterp->setRegion(gAgent.getRegion());
- LLVector3d water_pos(water_center_x, water_center_y, 256.f+DEFAULT_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
diff --git a/indra/newview/macutil_Prefix.h b/indra/newview/macutil_Prefix.h
index fd8e927a08..b54a764a62 100644
--- a/indra/newview/macutil_Prefix.h
+++ b/indra/newview/macutil_Prefix.h
@@ -33,7 +33,7 @@
*/
#include <Carbon/Carbon.h>
+#include "fix_macros.h"
-#undef check
#undef verify
#undef require
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ed636a40b2..ab45bd3d3b 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -51,6 +51,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"
@@ -104,7 +108,10 @@
#include "lltoolpie.h"
#include "llcurl.h"
#include "llnotifications.h"
-
+#include "llpathinglib.h"
+#include "llfloaterpathfindingconsole.h"
+#include "llfloaterpathfindingcharacters.h"
+#include "llpathfindingpathtool.h"
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -113,6 +120,8 @@
//#define DEBUG_INDICES
#endif
+bool gShiftFrame = false;
+
//cached settings
BOOL LLPipeline::RenderAvatarVP;
BOOL LLPipeline::VertexShaderEnable;
@@ -210,7 +219,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");
@@ -227,8 +236,13 @@ LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
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");
@@ -264,6 +278,7 @@ std::string gPoolNames[] =
void drawBox(const LLVector3& c, const LLVector3& 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)
{
@@ -403,9 +418,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),
@@ -432,6 +449,19 @@ LLPipeline::LLPipeline() :
mLightFunc = 0;
}
+void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
+{
+ 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()
{
LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT);
@@ -504,6 +534,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);
@@ -511,88 +546,86 @@ 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("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));
}
@@ -673,6 +706,8 @@ void LLPipeline::cleanup()
mInitialized = FALSE;
mDeferredVB = NULL;
+
+ mCubeVB = NULL;
}
//============================================================================
@@ -693,6 +728,12 @@ void LLPipeline::destroyGL()
{
LLVertexBuffer::sEnableVBOs = FALSE;
}
+
+ if (mMeshDirtyQueryObject)
+ {
+ glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ mMeshDirtyQueryObject = 0;
+ }
}
static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
@@ -738,18 +779,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 );
+ }
+
+ 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();
+ }
+ }
- //try to allocate screen buffers at requested resolution and samples
+ 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)
@@ -757,7 +837,7 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
samples /= 2;
if (allocateScreenBuffer(resX, resY, samples))
{ //success
- return;
+ return FBO_SUCCESS_LOWRES;
}
releaseScreenBuffers();
}
@@ -770,22 +850,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)
{
@@ -813,10 +894,6 @@ 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;
@@ -828,7 +905,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (!mScreen.allocate(resX, resY, GL_RGBA, 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
{
@@ -851,7 +928,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
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(sun_shadow_map_width,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;
}
}
else
@@ -862,7 +939,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
- U32 width = nhpo2(U32(resX*scale))/2;
+ U32 width = (U32) (resX*scale);
U32 height = width;
if (shadow_detail > 1)
@@ -881,9 +958,11 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
}
- // 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
{
@@ -942,6 +1021,7 @@ void LLPipeline::refreshCachedSettings()
LLPipeline::sUseOcclusion =
(!gUseWireframe
+ && LLGLSLShader::sNoFixedFunction
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
&& gSavedSettings.getBOOL("UseOcclusion")
&& gGLManager.mHasOcclusionQuery) ? 2 : 0;
@@ -1030,13 +1110,13 @@ void LLPipeline::releaseGLBuffers()
if (mNoiseMap)
{
- LLImageGL::deleteTextures(1, &mNoiseMap);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);
mNoiseMap = 0;
}
if (mTrueNoiseMap)
{
- LLImageGL::deleteTextures(1, &mTrueNoiseMap);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);
mTrueNoiseMap = 0;
}
@@ -1060,7 +1140,7 @@ void LLPipeline::releaseLUTBuffers()
{
if (mLightFunc)
{
- LLImageGL::deleteTextures(1, &mLightFunc);
+ LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
mLightFunc = 0;
}
}
@@ -1138,7 +1218,7 @@ void LLPipeline::createGLBuffers()
noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
}
- LLImageGL::generateTextures(1, &mNoiseMap);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 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, false);
@@ -1154,7 +1234,7 @@ void LLPipeline::createGLBuffers()
noise[i] = ll_frand()*2.0-1.0;
}
- LLImageGL::generateTextures(1, &mTrueNoiseMap);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 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, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
@@ -1210,7 +1290,7 @@ void LLPipeline::createLUTBuffers()
}
}
- LLImageGL::generateTextures(1, &mLightFunc);
+ LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 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, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
@@ -1349,7 +1429,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)
{
@@ -1640,6 +1720,21 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
+//static
+void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
+{
+ 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)
{
LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT);
@@ -1658,7 +1753,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LLFastTimer ftm(FTM_GEO_UPDATE);
+ LLFastTimer ftm(FTM_PIPELINE_CREATE);
LLMemType mt(LLMemType::MTYPE_PIPELINE_CREATE_OBJECTS);
LLTimer update_timer;
@@ -1819,7 +1914,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);
}
}
@@ -1940,11 +2049,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)
{
@@ -1966,7 +2076,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);
@@ -1978,25 +2088,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);
@@ -2010,25 +2120,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)
{
@@ -2061,19 +2171,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);
@@ -2087,7 +2197,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)
{
@@ -2095,7 +2205,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)
{
@@ -2103,7 +2213,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)
{
@@ -2214,8 +2324,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);
@@ -2259,7 +2367,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();
@@ -2291,7 +2408,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (bound_shader)
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
camera.disableUserClipPlane();
@@ -2335,7 +2452,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
{
- if (group->getData().empty())
+ if (group->isEmpty())
{
return;
}
@@ -2424,15 +2541,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);
@@ -2443,11 +2566,11 @@ void LLPipeline::doOcclusion(LLCamera& camera)
{
if (LLPipeline::sShadowRender)
{
- gDeferredShadowProgram.unbind();
+ gDeferredShadowCubeProgram.unbind();
}
else
{
- gOcclusionProgram.unbind();
+ gOcclusionCubeProgram.unbind();
}
}
@@ -2466,22 +2589,94 @@ 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();
@@ -2496,11 +2691,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())
@@ -2508,6 +2706,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();
@@ -2651,6 +2850,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
{
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())
{
@@ -2673,6 +2873,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
}
else
{
+
sCull->pushDrawable(drawablep);
}
@@ -2749,6 +2950,10 @@ 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);
@@ -2761,35 +2966,46 @@ 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();
}
@@ -2822,8 +3038,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;
@@ -2838,6 +3056,11 @@ 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);
@@ -2934,7 +3157,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
//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();
@@ -2945,7 +3168,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);
}
@@ -2960,9 +3183,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();
@@ -2992,7 +3215,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();
@@ -3014,7 +3237,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;
@@ -3033,7 +3256,7 @@ 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);
@@ -3150,13 +3373,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);
}
@@ -3189,7 +3412,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);
+ }
}
}
}
@@ -3215,11 +3442,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)
{
@@ -3227,7 +3458,7 @@ void renderPhysicalBeacons(LLDrawable* drawablep)
if (vobj
&& !vobj->isAvatar()
//&& !vobj->getParent()
- && vobj->usePhysics())
+ && vobj->flagUsePhysics())
{
if (gPipeline.sRenderBeacons)
{
@@ -3240,11 +3471,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)
{
@@ -3276,11 +3511,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)
{
@@ -3301,11 +3540,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)
{
@@ -3319,11 +3562,15 @@ 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)
{
@@ -3334,7 +3581,7 @@ void LLPipeline::postSort(LLCamera& camera)
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 ||
@@ -3350,23 +3597,9 @@ 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 &&
@@ -3436,11 +3669,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)
@@ -3514,7 +3779,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;
}
@@ -3523,6 +3792,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 ;
}
@@ -3818,6 +4114,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
@@ -3890,7 +4187,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
break;
}
- p->render(i);
+ if ( !p->getSkipRenderFlag() ) { p->render(i); }
}
poolp->endRenderPass(i);
LLVertexBuffer::unbind();
@@ -4005,7 +4302,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
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);
@@ -4047,7 +4344,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);
@@ -4064,7 +4361,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
break;
}
- p->renderDeferred(i);
+ if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
}
poolp->endDeferredPass(i);
LLVertexBuffer::unbind();
@@ -4100,7 +4397,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
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);
@@ -4134,7 +4431,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
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);
@@ -4324,7 +4621,7 @@ void LLPipeline::renderPhysicsDisplay()
}
}
- 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))
@@ -4353,14 +4650,341 @@ void LLPipeline::renderDebug()
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("tint", 1.f);
+ gPathfindingProgram.uniform1f("ambiance", 1.f);
+ gPathfindingProgram.uniform1f("alpha_scale", 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("alpha_scale", 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("tint", 1.f);
+ gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f("alpha_scale", 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("alpha_scale", 0.66f);
+ llPathingLibInstance->renderNavMesh();
+ }
+ else
+ {
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f("tint", 1.f);
+ gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 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("alpha_scale", 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("alpha_scale", 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("ambiance", 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("tint", gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f("alpha_scale", 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("ambiance", 1.f);
+ llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
+ }
+ else
+ {
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ gPathfindingProgram.uniform1f("ambiance", 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("ambiance", 1.f);
+ gPathfindingProgram.uniform1f("tint", 1.f);
+ gPathfindingProgram.uniform1f("alpha_scale", 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("tint", gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+
+ if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
+ { //draw hidden wireframe as darker and less opaque
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ gPathfindingProgram.uniform1f("ambiance", 1.f);
+ llPathingLibInstance->renderNavMesh();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ }
+ else
+ {
+ gPathfindingProgram.uniform1f("ambiance", ambiance);
+ llPathingLibInstance->renderNavMesh();
+ }
+
+ //render edges
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gPathfindingNoNormalsProgram.bind();
+ gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 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
@@ -4419,7 +5043,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))
@@ -4671,8 +5295,11 @@ void LLPipeline::renderDebug()
}
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools");
+
void LLPipeline::rebuildPools()
{
+ LLFastTimer t(FTM_REBUILD_POOLS);
LLMemType mt(LLMemType::MTYPE_PIPELINE_REBUILD_POOLS);
assertInitialized();
@@ -6219,7 +6846,10 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
for (S32 i = 0; i < drawable->getNumFaces(); i++)
{
LLFace* facep = drawable->getFace(i);
- facep->clearVertexBuffer();
+ if (facep)
+ {
+ facep->clearVertexBuffer();
+ }
}
}
@@ -6228,15 +6858,20 @@ 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)
{
@@ -6255,11 +6890,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;
@@ -6279,6 +6924,8 @@ 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)
@@ -6508,11 +7155,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;
@@ -6579,15 +7226,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
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
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
}
}
@@ -7088,7 +7728,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)
{
@@ -7098,8 +7738,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();
}
}
@@ -7179,13 +7819,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);
@@ -7395,10 +8035,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);
@@ -7466,12 +8102,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)
{
@@ -7517,25 +8158,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 ||
@@ -7553,16 +8176,13 @@ void LLPipeline::renderDeferredLighting()
}
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.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*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();
}
}
@@ -7575,6 +8195,9 @@ void LLPipeline::renderDeferredLighting()
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*s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
@@ -7587,7 +8210,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);
@@ -7605,36 +8228,17 @@ void LLPipeline::renderDeferredLighting()
sVisibleLightCount++;
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
- //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.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*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);
@@ -7666,8 +8270,6 @@ void LLPipeline::renderDeferredLighting()
LLVector4 light[max_count];
LLVector4 col[max_count];
-// glVertexPointer(2, GL_FLOAT, 0, vert);
-
F32 far_z = 0.f;
while (!fullscreen_lights.empty())
@@ -7943,9 +8545,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);
}
}
@@ -8196,6 +8798,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, false);
renderGeom(camera);
+
}
LLPipeline::sUnderWaterRender = FALSE;
@@ -8203,8 +8806,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
- LLRenderTarget::unbindTarget();
-
LLPipeline::sReflectionRender = FALSE;
if (!LLRenderTarget::sUseFBO)
@@ -8324,7 +8925,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
if (use_shader)
{
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
}
updateCull(shadow_cam, result);
@@ -8341,17 +8942,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();
{
@@ -8359,11 +8953,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)
{
@@ -8408,7 +9007,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
//glCullFace(GL_BACK);
- gDeferredShadowProgram.bind();
+ gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
doOcclusion(shadow_cam);
@@ -8683,6 +9282,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)
@@ -8690,6 +9291,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)
{
@@ -9439,7 +10042,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() &&
@@ -9452,6 +10055,12 @@ 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);
@@ -9507,101 +10116,114 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
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);
+ left.normalize3fast();
- LLVector4a up;
- up.load3(camera.getUpAxis().mV);
- up.mul(up);
- up.normalize3fast();
+ LLVector4a up;
+ up.load3(camera.getUpAxis().mV);
+ up.mul(up);
+ 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);
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ addDeferredAttachments(avatar->mImpostor);
+ }
- 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,GL_RGBA);
}
-
- 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();
+ }
if (LLPipeline::sRenderDeferred)
{
@@ -9618,6 +10240,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
}
{ //create alpha mask based on depth buffer (grey out if muted)
+ LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -9703,22 +10326,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();
}
@@ -9849,3 +10472,143 @@ void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& 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 5c623fc9f2..36abeca295 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -119,8 +119,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,6 +168,8 @@ public:
void unlinkDrawable(LLDrawable*);
+ static void removeMutedAVsLights(LLVOAvatar*);
+
// Object related methods
void markVisible(LLDrawable *drawablep, LLCamera& camera);
void markOccluder(LLSpatialGroup* group);
@@ -163,6 +182,7 @@ 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,
@@ -222,6 +242,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);
@@ -293,10 +314,10 @@ 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);
@@ -368,6 +389,12 @@ public:
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 +402,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 };
@@ -544,6 +573,9 @@ 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];
std::vector<LLVector3> mShadowFrustPoints[4];
@@ -595,6 +627,7 @@ 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;
@@ -652,6 +685,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;
diff --git a/indra/newview/res-sdl/lltoolpathfinding.BMP b/indra/newview/res-sdl/lltoolpathfinding.BMP
new file mode 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..4e8999ae0b
--- /dev/null
+++ b/indra/newview/res-sdl/lltoolpathfindingpathstartadd.BMP
Binary files differ
diff --git a/indra/newview/res/lltoolpathfinding.cur b/indra/newview/res/lltoolpathfinding.cur
new file mode 100644
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 100644
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 100644
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 100644
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 100644
index 0000000000..45e23e5161
--- /dev/null
+++ b/indra/newview/res/lltoolpathfindingpathstartadd.cur
Binary files differ
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index a53dece422..df75f3f697 100644
--- 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"
/////////////////////////////////////////////////////////////////////////////
//
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index b616e2327b..9bf2922033 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1,825 +1,861 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<colors>
- <!-- Named Colors -->
- <color
- name="EmphasisColor"
- value="0.38 0.694 0.573 1" />
- <color
- name="EmphasisColor_13"
- value="0.38 0.694 0.573 0.13" />
- <color
- name="EmphasisColor_35"
- value="0.38 0.694 0.573 0.35" />
- <color
- name="White"
- value="1 1 1 1" />
- <color
- name="White_05"
- value="1 1 1 0.05" />
- <color
- name="White_10"
- value="1 1 1 0.1" />
- <color
- name="White_25"
- value="1 1 1 0.25" />
- <color
- name="White_50"
- value="1 1 1 0.5" />
- <color
- name="LtGray"
- value="0.75 0.75 0.75 1" />
- <color
- name="LtGray_35"
- value="0.75 0.75 0.75 0.35" />
- <color
- name="LtGray_50"
- value="0.75 0.75 0.75 0.50" />
- <color
- name="Gray"
- value="0.5 0.5 0.5 1" />
- <color
- name="DkGray"
- value="0.125 0.125 0.125 1" />
- <color
- name="DkGray_66"
- value="0.125 0.125 0.125 .66" />
- <color
- name="DkGray2"
- value="0.169 0.169 0.169 1" />
- <color
- name="MouseGray"
- value="0.191 0.191 0.191 1" />
- <color
- name="Black"
- value="0 0 0 1" />
- <colork
- name="Black_10"
- value="0 0 0 0.1" />
- <color
- name="Black_25"
- value="0 0 0 0.25" />
- <color
- name="Black_50"
- value="0 0 0 0.5" />
- <color
- name="FrogGreen"
- value="0.26 0.345 0.263 1" />
- <color
- name="Red"
- value="1 0 0 1" />
- <color
- name="Blue"
- value="0 0 1 1" />
- <color
- name="Yellow"
- value="1 1 0 1" />
- <color
- name="Green"
- value="0 1 0 1" />
- <color
- name="Transparent"
- value="0 0 0 0" />
- <color
- name="Purple"
- value="1 0 1 1" />
- <color
- name="Lime"
- value=".8 1 .73 1" />
- <color
- name="LtYellow"
- value="1 1 .79 1" />
- <color
- name="DrYellow"
- value="1 0.86 0 1" />
- <color
- name="LtOrange"
- value="1 .85 .73 1" />
- <color
- name="MdBlue"
- value=".07 .38 .51 1" />
+ <!-- Named Colors -->
+ <color
+ name="EmphasisColor"
+ value="0.38 0.694 0.573 1" />
+ <color
+ name="EmphasisColor_13"
+ value="0.38 0.694 0.573 0.13" />
+ <color
+ name="EmphasisColor_35"
+ value="0.38 0.694 0.573 0.35" />
+ <color
+ name="White"
+ value="1 1 1 1" />
+ <color
+ name="White_05"
+ value="1 1 1 0.05" />
+ <color
+ name="White_10"
+ value="1 1 1 0.1" />
+ <color
+ name="White_25"
+ value="1 1 1 0.25" />
+ <color
+ name="White_50"
+ value="1 1 1 0.5" />
+ <color
+ name="LtGray"
+ value="0.75 0.75 0.75 1" />
+ <color
+ name="LtGray_35"
+ value="0.75 0.75 0.75 0.35" />
+ <color
+ name="LtGray_50"
+ value="0.75 0.75 0.75 0.50" />
+ <color
+ name="Gray"
+ value="0.5 0.5 0.5 1" />
+ <color
+ name="DkGray"
+ value="0.125 0.125 0.125 1" />
+ <color
+ name="DkGray_66"
+ value="0.125 0.125 0.125 .66" />
+ <color
+ name="DkGray2"
+ value="0.169 0.169 0.169 1" />
+ <color
+ name="MouseGray"
+ value="0.191 0.191 0.191 1" />
+ <color
+ name="Black"
+ value="0 0 0 1" />
+ <colork
+ name="Black_10"
+ value="0 0 0 0.1" />
+ <color
+ name="Black_25"
+ value="0 0 0 0.25" />
+ <color
+ name="Black_50"
+ value="0 0 0 0.5" />
+ <color
+ name="FrogGreen"
+ value="0.26 0.345 0.263 1" />
+ <color
+ name="Red"
+ value="1 0 0 1" />
+ <color
+ name="Blue"
+ value="0 0 1 1" />
+ <color
+ name="Yellow"
+ value="1 1 0 1" />
+ <color
+ name="Green"
+ value="0 1 0 1" />
+ <color
+ name="Transparent"
+ value="0 0 0 0" />
+ <color
+ name="Purple"
+ value="1 0 1 1" />
+ <color
+ name="Lime"
+ value=".8 1 .73 1" />
+ <color
+ name="LtYellow"
+ value="1 1 .79 1" />
+ <color
+ name="DrYellow"
+ value="1 0.86 0 1" />
+ <color
+ name="LtOrange"
+ value="1 .85 .73 1" />
+ <color
+ name="MdBlue"
+ value=".07 .38 .51 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="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
- the viewer generates many warnings on startup. -->
+ Leave this here until all Unused? are removed below, otherwise
+ the viewer generates many warnings on startup. -->
<color
- name="Unused?"
- value=".831 1 0 1" />
+ name="Unused?"
+ value=".831 1 0 1" />
<!-- UI Definitions -->
- <color
- name="AccordionHeaderTextColor"
- reference="LtGray" />
- <color
- name="AgentChatColor"
- reference="White" />
- <color
- name="AlertBoxColor"
- value="0.24 0.24 0.24 1" />
- <color
- name="AlertCautionBoxColor"
- value="1 0.82 0.46 1" />
- <color
- name="AlertCautionTextColor"
- reference="LtYellow" />
- <color
- name="AvatarListItemIconDefaultColor"
- reference="White" />
- <color
- name="AvatarListItemIconOnlineColor"
- reference="White" />
- <color
- name="AvatarListItemIconOfflineColor"
- value="0.5 0.5 0.5 0.5" />
- <color
- name="AvatarListItemIconVoiceInvitedColor"
- reference="AvatarListItemIconOfflineColor" />
- <color
- name="AvatarListItemIconVoiceJoinedColor"
- reference="AvatarListItemIconOnlineColor" />
- <color
- name="AvatarListItemIconVoiceLeftColor"
- reference="AvatarListItemIconOfflineColor" />
- <color
- name="BadgeImageColor"
- value="1.0 0.40 0.0 1.0" />
- <color
- name="BadgeBorderColor"
- value="0.9 0.9 0.9 1.0" />
- <color
- name="BadgeLabelColor"
- reference="White" />
- <color
- name="ButtonBorderColor"
- reference="Unused?" />
- <color
- name="ButtonCautionImageColor"
- reference="Unused?" />
- <color
- name="ButtonColor"
- reference="Unused?" />
- <color
- name="ButtonFlashBgColor"
- reference="Unused?" />
- <color
- name="ButtonImageColor"
- reference="White" />
- <color
- name="ButtonLabelColor"
- reference="LtGray" />
- <color
- name="ButtonLabelDisabledColor"
- reference="White_25" />
- <color
- name="ButtonLabelSelectedColor"
- reference="White" />
- <color
- name="ButtonLabelSelectedDisabledColor"
- reference="White_25" />
- <color
- name="ButtonSelectedBgColor"
- reference="Unused?" />
- <color
- name="ButtonSelectedColor"
- reference="Unused?" />
- <color
- name="ButtonUnselectedBgColor"
- reference="Unused?" />
- <color
- name="ButtonUnselectedFgColor"
- reference="Unused?" />
- <color
- name="ChatHistoryBgColor"
- reference="Transparent" />
- <color
- name="ChatHistoryTextColor"
- reference="LtGray" />
- <color
- name="ChicletFlashColor"
- value="0.114 0.65 0.1" />
- <color
- name="ColorDropShadow"
- reference="Black_50" />
- <color
- name="ColorPaletteEntry01"
- reference="Black" />
- <color
- name="ColorPaletteEntry02"
- reference="Gray" />
- <color
- name="ColorPaletteEntry03"
- value="0.5 0 0 1" />
- <color
- name="ColorPaletteEntry04"
- value="0.5 0.5 0 1" />
- <color
- name="ColorPaletteEntry05"
- value="0 0.5 0 1" />
- <color
- name="ColorPaletteEntry06"
- value="0 0.5 0.5 1" />
- <color
- name="ColorPaletteEntry07"
- value="0 0 0.5 1" />
- <color
- name="ColorPaletteEntry08"
- value="0.5 0 0.5 1" />
- <color
- name="ColorPaletteEntry09"
- value="0.5 0.5 0 1" />
- <color
- name="ColorPaletteEntry10"
- value="0 0.25 0.25 1" />
- <color
- name="ColorPaletteEntry11"
- value="0 0.5 1 1" />
- <color
- name="ColorPaletteEntry12"
- value="0 0.25 0.5 1" />
- <color
- name="ColorPaletteEntry13"
- value="0.5 0 1 1" />
- <color
- name="ColorPaletteEntry14"
- value="0.5 0.25 0 1" />
- <color
- name="ColorPaletteEntry15"
- reference="White" />
- <color
- name="ColorPaletteEntry16"
- reference="LtYellow" />
- <color
- name="ColorPaletteEntry17"
- reference="White" />
- <color
- name="ColorPaletteEntry18"
- reference="LtGray" />
- <color
- name="ColorPaletteEntry19"
- reference="Red" />
- <color
- name="ColorPaletteEntry20"
- reference="Yellow" />
- <color
- name="ColorPaletteEntry21"
- reference="Green" />
- <color
- name="ColorPaletteEntry22"
- value="0 1 1 1" />
- <color
- name="ColorPaletteEntry23"
- reference="Blue" />
- <color
- name="ColorPaletteEntry24"
- reference="Purple" />
- <color
- name="ColorPaletteEntry25"
- value="1 1 0.5 1" />
- <color
- name="ColorPaletteEntry26"
- value="0 1 0.5 1" />
- <color
- name="ColorPaletteEntry27"
- value="0.5 1 1 1" />
- <color
- name="ColorPaletteEntry28"
- value="0.5 0.5 1 1" />
- <color
- name="ColorPaletteEntry29"
- value="1 0 0.5 1" />
- <color
- name="ColorPaletteEntry30"
- value="1 0.5 0 1" />
- <color
- name="ColorPaletteEntry31"
- reference="White" />
- <color
- name="ColorPaletteEntry32"
- reference="White" />
- <color
- name="ComboListBgColor"
- reference="DkGray" />
- <color
- name="ConsoleBackground"
- reference="Black" />
- <color
- name="ContextSilhouetteColor"
- reference="EmphasisColor" />
- <color
- name="DefaultHighlightDark"
- reference="White_10" />
- <color
- name="DefaultHighlightLight"
- reference="White_25" />
- <color
- name="DefaultShadowDark"
- reference="Black_50" />
- <color
- name="DefaultShadowLight"
- reference="Black_50" />
- <color
- name="EffectColor"
- reference="White" />
- <color
- name="FilterBackgroundColor"
- reference="Black" />
- <color
- name="FilterTextColor"
- value="0.38 0.69 0.57 1" />
- <color
- name="FloaterButtonImageColor"
- reference="LtGray" />
- <color
- name="FloaterDefaultBackgroundColor"
- reference="DkGray_66" />
- <color
- name="FloaterFocusBackgroundColor"
- reference="DkGray2" />
- <color
- name="FloaterFocusBorderColor"
- reference="Black_50" />
- <color
- name="FloaterUnfocusBorderColor"
- reference="Black_50" />
- <color
- name="FocusColor"
- reference="EmphasisColor" />
- <color
- name="FolderViewLoadingMessageTextColor"
- value="0.3344 0.5456 0.5159 1" />
- <color
- name="GridFocusPointColor"
- reference="White_50" />
- <color
- name="GridlineBGColor"
- value="0.92 0.92 1 0.78" />
- <color
- name="GridlineColor"
- reference="White" />
- <color
- name="GridlineShadowColor"
- value="0 0 0 0.31" />
- <color
- name="GroupNotifyBoxColor"
- value="0.3344 0.5456 0.5159 1" />
- <color
- name="GroupNotifyTextColor"
- reference="White"/>
- <color
- name="GroupNotifyDimmedTextColor"
- reference="LtGray" />
- <color
- name="GroupOverTierColor"
- value="0.43 0.06 0.06 1" />
- <color
- name="HTMLLinkColor"
- reference="EmphasisColor" />
- <color
- name="HealthTextColor"
- reference="White" />
- <color
- name="HelpBgColor"
- reference="Unused?" />
- <color
- name="HelpFgColor"
- reference="Unused?" />
- <color
- name="HelpScrollHighlightColor"
- reference="Unused?" />
- <color
- name="HelpScrollShadowColor"
- reference="Unused?" />
- <color
- name="HelpScrollThumbColor"
- reference="Unused?" />
- <color
- name="HelpScrollTrackColor"
- reference="Unused?" />
- <color
- name="HighlightChildColor"
- reference="Yellow" />
- <color
- name="HighlightInspectColor"
- value="1 0 1 1" />
- <color
- name="HighlightParentColor"
- value="0.67 0.83 0.96 1" />
- <color
- name="IMHistoryBgColor"
- reference="Unused?" />
- <color
- name="IMHistoryTextColor"
- reference="Unused?" />
- <color
- name="IconDisabledColor"
- reference="White_25" />
- <color
- name="IconEnabledColor"
- reference="White" />
- <color
- name="InventoryBackgroundColor"
- reference="DkGray2" />
- <color
- name="InventoryFocusOutlineColor"
- reference="White_25" />
- <color
- name="InventoryItemSuffixColor"
- reference="White_25" />
- <color
- name="InventoryItemLibraryColor"
- reference="EmphasisColor" />
- <color
- name="InventoryItemLinkColor"
- reference="LtGray_50" />
- <color
- name="InventoryMouseOverColor"
- reference="LtGray_35" />
- <color
- name="InventorySearchStatusColor"
- reference="EmphasisColor" />
- <color
- name="LabelDisabledColor"
- reference="White_25" />
- <color
- name="LabelSelectedColor"
- reference="White" />
- <color
- name="LabelSelectedDisabledColor"
- reference="White_25" />
- <color
- name="LabelTextColor"
- reference="LtGray" />
- <color
- name="LoginProgressBarBgColor"
- reference="Unused?" />
- <color
- name="LoginProgressBarFgColor"
- reference="Unused?" />
- <color
- name="LoginProgressBoxBorderColor"
- value="0 0.12 0.24 0" />
- <color
- name="LoginProgressBoxCenterColor"
- value="0 0 0 0.78" />
- <color
- name="LoginProgressBoxShadowColor"
- value="0 0 0 0.78" />
- <color
- name="LoginProgressBoxTextColor"
- reference="White" />
- <color
- name="MapAvatarColor"
- reference="Green" />
- <color
- name="MapAvatarFriendColor"
- reference="Yellow" />
- <color
- name="MapAvatarSelfColor"
- value="0.53125 0 0.498047 1" />
- <color
- name="MapFrustumColor"
- reference="White_10" />
- <color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
- <color
- name="MapTrackColor"
- reference="Red" />
- <color
- name="MapTrackDisabledColor"
- value="0.5 0 0 1" />
- <color
- name="MenuBarBgColor"
- reference="DkGray" />
- <color
- name="MenuBarGodBgColor"
- reference="FrogGreen" />
- <color
- name="MenuDefaultBgColor"
- reference="DkGray2" />
- <color
- name="MenuItemDisabledColor"
- reference="LtGray_50" />
- <color
- name="MenuItemEnabledColor"
- reference="LtGray" />
- <color
- name="MenuItemHighlightBgColor"
- reference="EmphasisColor_35" />
- <color
- name="MenuItemHighlightFgColor"
- reference="White" />
- <color
- name="MenuNonProductionBgColor"
- reference="Black" />
- <color
- name="MenuNonProductionGodBgColor"
- value="0.263 0.325 0.345 1" />
- <color
- name="MenuPopupBgColor"
- reference="DkGray2" />
- <color
- name="ModelUploaderLabels"
- value="1 0.6 0 1" />
- <color
- name="MultiSliderDisabledThumbColor"
- reference="Black" />
- <color
- name="MultiSliderThumbCenterColor"
- reference="White" />
- <color
- name="MultiSliderThumbCenterSelectedColor"
- reference="Green" />
- <color
- name="MultiSliderThumbOutlineColor"
- reference="Unused?" />
- <color
- name="MultiSliderTrackColor"
- reference="LtGray" />
- <color
- name="MultiSliderTriangleColor"
- reference="Yellow" />
+ <color
+ name="AccordionHeaderTextColor"
+ reference="LtGray" />
+ <color
+ name="AgentChatColor"
+ reference="White" />
+ <color
+ name="AlertBoxColor"
+ value="0.24 0.24 0.24 1" />
+ <color
+ name="AlertCautionBoxColor"
+ value="1 0.82 0.46 1" />
+ <color
+ name="AlertCautionTextColor"
+ reference="LtYellow" />
+ <color
+ name="AvatarListItemIconDefaultColor"
+ reference="White" />
+ <color
+ name="AvatarListItemIconOnlineColor"
+ reference="White" />
+ <color
+ name="AvatarListItemIconOfflineColor"
+ value="0.5 0.5 0.5 0.5" />
+ <color
+ name="AvatarListItemIconVoiceInvitedColor"
+ reference="AvatarListItemIconOfflineColor" />
+ <color
+ name="AvatarListItemIconVoiceJoinedColor"
+ reference="AvatarListItemIconOnlineColor" />
+ <color
+ name="AvatarListItemIconVoiceLeftColor"
+ reference="AvatarListItemIconOfflineColor" />
+ <color
+ name="BadgeImageColor"
+ value="1.0 0.40 0.0 1.0" />
+ <color
+ name="BadgeBorderColor"
+ value="0.9 0.9 0.9 1.0" />
+ <color
+ name="BadgeLabelColor"
+ reference="White" />
+ <color
+ name="ButtonBorderColor"
+ reference="Unused?" />
+ <color
+ name="ButtonCautionImageColor"
+ reference="Unused?" />
+ <color
+ name="ButtonColor"
+ reference="Unused?" />
+ <color
+ name="ButtonFlashBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonImageColor"
+ reference="White" />
+ <color
+ name="ButtonLabelColor"
+ reference="LtGray" />
+ <color
+ name="ButtonLabelDisabledColor"
+ reference="White_25" />
+ <color
+ name="ButtonLabelSelectedColor"
+ reference="White" />
+ <color
+ name="ButtonLabelSelectedDisabledColor"
+ reference="White_25" />
+ <color
+ name="ButtonSelectedBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonSelectedColor"
+ reference="Unused?" />
+ <color
+ name="ButtonUnselectedBgColor"
+ reference="Unused?" />
+ <color
+ name="ButtonUnselectedFgColor"
+ reference="Unused?" />
+ <color
+ name="ChatHistoryBgColor"
+ reference="Transparent" />
+ <color
+ name="ChatHistoryTextColor"
+ reference="LtGray" />
+ <color
+ name="ChicletFlashColor"
+ value="0.114 0.65 0.1" />
+ <color
+ name="ColorDropShadow"
+ reference="Black_50" />
+ <color
+ name="ColorPaletteEntry01"
+ reference="Black" />
+ <color
+ name="ColorPaletteEntry02"
+ reference="Gray" />
+ <color
+ name="ColorPaletteEntry03"
+ value="0.5 0 0 1" />
+ <color
+ name="ColorPaletteEntry04"
+ value="0.5 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry05"
+ value="0 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry06"
+ value="0 0.5 0.5 1" />
+ <color
+ name="ColorPaletteEntry07"
+ value="0 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry08"
+ value="0.5 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry09"
+ value="0.5 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry10"
+ value="0 0.25 0.25 1" />
+ <color
+ name="ColorPaletteEntry11"
+ value="0 0.5 1 1" />
+ <color
+ name="ColorPaletteEntry12"
+ value="0 0.25 0.5 1" />
+ <color
+ name="ColorPaletteEntry13"
+ value="0.5 0 1 1" />
+ <color
+ name="ColorPaletteEntry14"
+ value="0.5 0.25 0 1" />
+ <color
+ name="ColorPaletteEntry15"
+ reference="White" />
+ <color
+ name="ColorPaletteEntry16"
+ reference="LtYellow" />
+ <color
+ name="ColorPaletteEntry17"
+ reference="White" />
+ <color
+ name="ColorPaletteEntry18"
+ reference="LtGray" />
+ <color
+ name="ColorPaletteEntry19"
+ reference="Red" />
+ <color
+ name="ColorPaletteEntry20"
+ reference="Yellow" />
+ <color
+ name="ColorPaletteEntry21"
+ reference="Green" />
+ <color
+ name="ColorPaletteEntry22"
+ value="0 1 1 1" />
+ <color
+ name="ColorPaletteEntry23"
+ reference="Blue" />
+ <color
+ name="ColorPaletteEntry24"
+ reference="Purple" />
+ <color
+ name="ColorPaletteEntry25"
+ value="1 1 0.5 1" />
+ <color
+ name="ColorPaletteEntry26"
+ value="0 1 0.5 1" />
+ <color
+ name="ColorPaletteEntry27"
+ value="0.5 1 1 1" />
+ <color
+ name="ColorPaletteEntry28"
+ value="0.5 0.5 1 1" />
+ <color
+ name="ColorPaletteEntry29"
+ value="1 0 0.5 1" />
+ <color
+ name="ColorPaletteEntry30"
+ value="1 0.5 0 1" />
+ <color
+ name="ColorPaletteEntry31"
+ reference="White" />
+ <color
+ name="ColorPaletteEntry32"
+ reference="White" />
+ <color
+ name="ComboListBgColor"
+ reference="DkGray" />
+ <color
+ name="ConsoleBackground"
+ reference="Black" />
+ <color
+ name="ContextSilhouetteColor"
+ reference="EmphasisColor" />
+ <color
+ name="DefaultHighlightDark"
+ reference="White_10" />
+ <color
+ name="DefaultHighlightLight"
+ reference="White_25" />
+ <color
+ name="DefaultShadowDark"
+ reference="Black_50" />
+ <color
+ name="DefaultShadowLight"
+ reference="Black_50" />
+ <color
+ name="EffectColor"
+ reference="White" />
+ <color
+ name="FilterBackgroundColor"
+ reference="Black" />
+ <color
+ name="FilterTextColor"
+ value="0.38 0.69 0.57 1" />
+ <color
+ name="FloaterButtonImageColor"
+ reference="LtGray" />
+ <color
+ name="FloaterDefaultBackgroundColor"
+ reference="DkGray_66" />
+ <color
+ name="FloaterFocusBackgroundColor"
+ reference="DkGray2" />
+ <color
+ name="FloaterFocusBorderColor"
+ reference="Black_50" />
+ <color
+ name="FloaterUnfocusBorderColor"
+ reference="Black_50" />
+ <color
+ name="FocusColor"
+ reference="EmphasisColor" />
+ <color
+ name="FolderViewLoadingMessageTextColor"
+ value="0.3344 0.5456 0.5159 1" />
+ <color
+ name="GridFocusPointColor"
+ reference="White_50" />
+ <color
+ name="GridlineBGColor"
+ value="0.92 0.92 1 0.78" />
+ <color
+ name="GridlineColor"
+ reference="White" />
+ <color
+ name="GridlineShadowColor"
+ value="0 0 0 0.31" />
+ <color
+ name="GroupNotifyBoxColor"
+ value="0.3344 0.5456 0.5159 1" />
+ <color
+ name="GroupNotifyTextColor"
+ reference="White"/>
+ <color
+ name="GroupNotifyDimmedTextColor"
+ reference="LtGray" />
+ <color
+ name="GroupOverTierColor"
+ value="0.43 0.06 0.06 1" />
+ <color
+ name="HTMLLinkColor"
+ reference="EmphasisColor" />
+ <color
+ name="HealthTextColor"
+ reference="White" />
+ <color
+ name="HelpBgColor"
+ reference="Unused?" />
+ <color
+ name="HelpFgColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollHighlightColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollShadowColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollThumbColor"
+ reference="Unused?" />
+ <color
+ name="HelpScrollTrackColor"
+ reference="Unused?" />
+ <color
+ name="HighlightChildColor"
+ reference="Yellow" />
+ <color
+ name="HighlightInspectColor"
+ value="1 0 1 1" />
+ <color
+ name="HighlightParentColor"
+ value="0.67 0.83 0.96 1" />
+ <color
+ name="IMHistoryBgColor"
+ reference="Unused?" />
+ <color
+ name="IMHistoryTextColor"
+ reference="Unused?" />
+ <color
+ name="IconDisabledColor"
+ reference="White_25" />
+ <color
+ name="IconEnabledColor"
+ reference="White" />
+ <color
+ name="InventoryBackgroundColor"
+ reference="DkGray2" />
+ <color
+ name="InventoryFocusOutlineColor"
+ reference="White_25" />
+ <color
+ name="InventoryItemSuffixColor"
+ reference="White_25" />
+ <color
+ name="InventoryItemLibraryColor"
+ reference="EmphasisColor" />
+ <color
+ name="InventoryItemLinkColor"
+ reference="LtGray_50" />
+ <color
+ name="InventoryMouseOverColor"
+ reference="LtGray_35" />
+ <color
+ name="InventorySearchStatusColor"
+ reference="EmphasisColor" />
+ <color
+ name="LabelDisabledColor"
+ reference="White_25" />
+ <color
+ name="LabelSelectedColor"
+ reference="White" />
+ <color
+ name="LabelSelectedDisabledColor"
+ reference="White_25" />
+ <color
+ name="LabelTextColor"
+ reference="LtGray" />
+ <color
+ name="LoginProgressBarBgColor"
+ reference="Unused?" />
+ <color
+ name="LoginProgressBarFgColor"
+ reference="Unused?" />
+ <color
+ name="LoginProgressBoxBorderColor"
+ value="0 0.12 0.24 0" />
+ <color
+ name="LoginProgressBoxCenterColor"
+ value="0 0 0 0.78" />
+ <color
+ name="LoginProgressBoxShadowColor"
+ value="0 0 0 0.78" />
+ <color
+ name="LoginProgressBoxTextColor"
+ reference="White" />
+ <color
+ name="MapAvatarColor"
+ reference="Green" />
+ <color
+ name="MapAvatarFriendColor"
+ reference="Yellow" />
+ <color
+ name="MapAvatarSelfColor"
+ value="0.53125 0 0.498047 1" />
+ <color
+ name="MapFrustumColor"
+ reference="White_10" />
+ <color
+ name="MapFrustumRotatingColor"
+ value="1 1 1 0.2" />
+ <color
+ name="MapTrackColor"
+ reference="Red" />
+ <color
+ name="MapTrackDisabledColor"
+ value="0.5 0 0 1" />
+ <color
+ name="MenuBarBgColor"
+ reference="DkGray" />
+ <color
+ name="MenuBarGodBgColor"
+ reference="FrogGreen" />
+ <color
+ name="MenuDefaultBgColor"
+ reference="DkGray2" />
+ <color
+ name="MenuItemDisabledColor"
+ reference="LtGray_50" />
+ <color
+ name="MenuItemEnabledColor"
+ reference="LtGray" />
+ <color
+ name="MenuItemHighlightBgColor"
+ reference="EmphasisColor_35" />
+ <color
+ name="MenuItemHighlightFgColor"
+ reference="White" />
+ <color
+ name="MenuNonProductionBgColor"
+ reference="Black" />
+ <color
+ name="MenuNonProductionGodBgColor"
+ value="0.263 0.325 0.345 1" />
+ <color
+ name="MenuPopupBgColor"
+ reference="DkGray2" />
+ <color
+ name="ModelUploaderLabels"
+ value="1 0.6 0 1" />
+ <color
+ name="MultiSliderDisabledThumbColor"
+ reference="Black" />
+ <color
+ name="MultiSliderThumbCenterColor"
+ reference="White" />
+ <color
+ name="MultiSliderThumbCenterSelectedColor"
+ reference="Green" />
+ <color
+ name="MultiSliderThumbOutlineColor"
+ reference="Unused?" />
+ <color
+ name="MultiSliderTrackColor"
+ reference="LtGray" />
+ <color
+ name="MultiSliderTriangleColor"
+ reference="Yellow" />
<!--
- <color
+ <color
name="NameTagBackground"
value="0.85 0.85 0.85 0.80" />
- -->
- <color
+ -->
+ <color
name="NameTagBackground"
value="0 0 0 1" />
- <color
- name="NameTagChat"
- reference="White" />
- <color
- name="NameTagFriend"
- value="0.447 0.784 0.663 1" />
- <color
- name="NameTagLegacy"
- reference="White" />
- <color
- name="NameTagMatch"
- reference="White" />
- <color
- name="NameTagMismatch"
- reference="White" />
- <color
- name="NetMapBackgroundColor"
- value="0 0 0 1" />
- <color
- name="NetMapGroupOwnAboveWater"
- reference="Purple" />
- <color
- name="NetMapGroupOwnBelowWater"
- value="0.78 0 0.78 1" />
- <color
- name="NetMapOtherOwnAboveWater"
- value="0.24 0.24 0.24 1" />
- <color
- name="NetMapOtherOwnBelowWater"
- value="0.12 0.12 0.12 1" />
- <color
- name="NetMapYouOwnAboveWater"
- value="0 1 1 1" />
- <color
- name="NetMapYouOwnBelowWater"
- value="0 0.78 0.78 1" />
- <color
- name="NotifyBoxColor"
- value="LtGray" />
- <color
- name="NotifyCautionBoxColor"
- value="1 0.82 0.46 1" />
- <color
- name="NotifyCautionWarnColor"
- reference="White" />
- <color
- name="NotifyTextColor"
- reference="White" />
- <color
- name="ObjectBubbleColor"
- reference="DkGray_66" />
- <color
- name="ObjectChatColor"
- reference="EmphasisColor" />
- <color
- name="OverdrivenColor"
- reference="Red" />
- <color
- name="PanelDefaultBackgroundColor"
- reference="DkGray" />
- <color
- name="PanelDefaultHighlightLight"
- reference="White_50" />
- <color
- name="PanelFocusBackgroundColor"
- reference="DkGray2" />
- <color
- name="PanelNotificationBackground"
- value="1 0.3 0.3 0" />
- <color
- name="ParcelHoverColor"
- reference="White" />
- <color
- name="PieMenuBgColor"
- value="0.24 0.24 0.24 0.59" />
- <color
- name="PieMenuLineColor"
- value="0 0 0 0.5" />
- <color
- name="PieMenuSelectedColor"
- value="0.72 0.72 0.74 0.3" />
- <color
- name="PropertyColorAuction"
- value="0.5 0 1 0.4" />
- <color
- name="PropertyColorAvail"
- reference="Transparent" />
- <color
- name="PropertyColorForSale"
- value="1 0.5 0 0.4" />
- <color
- name="PropertyColorGroup"
- value="0 0.72 0.72 0.4" />
- <color
- name="PropertyColorOther"
- value="1 0 0 0.4" />
- <color
- name="PropertyColorSelf"
- value="0 1 0 0.4" />
- <color
- name="ScriptBgReadOnlyColor"
- value="0.39 0.39 0.39 1" />
- <color
- name="ScriptErrorColor"
- reference="Red" />
- <color
- name="ScrollBGStripeColor"
- reference="Transparent" />
- <color
- name="ScrollBgReadOnlyColor"
+ <color
+ name="NameTagChat"
+ reference="White" />
+ <color
+ name="NameTagFriend"
+ value="0.447 0.784 0.663 1" />
+ <color
+ name="NameTagLegacy"
+ reference="White" />
+ <color
+ name="NameTagMatch"
+ reference="White" />
+ <color
+ name="NameTagMismatch"
+ reference="White" />
+ <color
+ name="NetMapBackgroundColor"
+ value="0 0 0 1" />
+ <color
+ name="NetMapGroupOwnAboveWater"
+ reference="Purple" />
+ <color
+ name="NetMapGroupOwnBelowWater"
+ value="0.78 0 0.78 1" />
+ <color
+ name="NetMapOtherOwnAboveWater"
+ value="0.24 0.24 0.24 1" />
+ <color
+ name="NetMapOtherOwnBelowWater"
+ value="0.12 0.12 0.12 1" />
+ <color
+ name="NetMapYouOwnAboveWater"
+ value="0 1 1 1" />
+ <color
+ name="NetMapYouOwnBelowWater"
+ value="0 0.78 0.78 1" />
+ <color
+ name="NotifyBoxColor"
+ value="LtGray" />
+ <color
+ name="NotifyCautionBoxColor"
+ value="1 0.82 0.46 1" />
+ <color
+ name="NotifyCautionWarnColor"
+ reference="White" />
+ <color
+ name="NotifyTextColor"
+ reference="White" />
+ <color
+ name="ObjectBubbleColor"
+ reference="DkGray_66" />
+ <color
+ name="ObjectChatColor"
+ reference="EmphasisColor" />
+ <color
+ name="OverdrivenColor"
+ reference="Red" />
+ <color
+ name="PanelDefaultBackgroundColor"
+ reference="DkGray" />
+ <color
+ name="PanelDefaultHighlightLight"
+ reference="White_50" />
+ <color
+ name="PanelFocusBackgroundColor"
+ reference="DkGray2" />
+ <color
+ name="PanelNotificationBackground"
+ value="1 0.3 0.3 0" />
+ <color
+ name="ParcelHoverColor"
+ reference="White" />
+ <color
+ name="PathfindingErrorColor"
+ reference="LtRed" />
+ <color
+ name="PathfindingWarningColor"
+ reference="DrYellow" />
+ <color
+ name="PathfindingGoodColor"
+ 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
+ name="PieMenuLineColor"
+ value="0 0 0 0.5" />
+ <color
+ name="PieMenuSelectedColor"
+ value="0.72 0.72 0.74 0.3" />
+ <color
+ name="PropertyColorAuction"
+ value="0.5 0 1 0.4" />
+ <color
+ name="PropertyColorAvail"
reference="Transparent" />
- <color
- name="ScrollBgWriteableColor"
- reference="White_05" />
- <color
- name="ScrollDisabledColor"
- reference="White_25" />
- <color
- name="ScrollHighlightedColor"
- reference="Unused?" />
- <color
- name="ScrollHoveredColor"
- reference="EmphasisColor_13" />
- <color
- name="ScrollSelectedBGColor"
- reference="EmphasisColor_35" />
- <color
- name="ScrollSelectedFGColor"
- reference="White" />
- <color
- name="ScrollUnselectedColor"
- reference="LtGray" />
- <color
- name="ScrollbarThumbColor"
- reference="White" />
- <color
- name="ScrollbarTrackColor"
- reference="Black" />
- <color
- name="SelectedOutfitTextColor"
- reference="EmphasisColor" />
- <color
- name="SilhouetteChildColor"
- value="0.13 0.42 0.77 1" />
- <color
- name="SilhouetteParentColor"
- reference="Yellow" />
- <color
- name="SliderDisabledThumbColor"
- reference="White_25" />
- <color
- name="SliderThumbCenterColor"
- reference="White" />
- <color
- name="SliderThumbOutlineColor"
- reference="White" />
- <color
- name="SliderTrackColor"
- reference="Unused?" />
- <color
- name="SpeakingColor"
- reference="FrogGreen" />
- <color
- name="SystemChatColor"
- reference="LtGray" />
- <color
- name="TextBgFocusColor"
- reference="White" />
- <color
- name="TextBgReadOnlyColor"
- reference="White_05" />
- <color
- name="TextBgWriteableColor"
- reference="LtGray" />
- <color
- name="TextCursorColor"
- reference="Black" />
- <color
- name="TextDefaultColor"
- reference="Black" />
- <color
- name="TextEmbeddedItemColor"
- value="0 0 0.5 1" />
- <color
- name="TextEmbeddedItemReadOnlyColor"
- reference="Unused?" />
- <color
- name="TextFgColor"
- value="0.102 0.102 0.102 1" />
- <color
- name="TextFgReadOnlyColor"
- reference="LtGray" />
- <color
- name="TextFgTentativeColor"
- value="0.4 0.4 0.4 1" />
- <color
- name="TimeTextColor"
- reference="LtGray" />
- <color
- name="TitleBarFocusColor"
- reference="White_10" />
- <color
- name="ToastBackground"
- value="0.3 0.3 0.3 0" />
- <color
- name="ToolTipBgColor"
- value="0.937 0.89 0.655 1" />
- <color
- name="ToolTipBorderColor"
- value="0.812 0.753 0.451 1" />
- <color
- name="ToolTipTextColor"
- reference="DkGray2" />
- <color
- name="InspectorTipTextColor"
- reference="LtGray" />
- <color
- name="UserChatColor"
- reference="White" />
- <color
- name="llOwnerSayChatColor"
- reference="LtYellow" />
+ <color
+ name="PropertyColorForSale"
+ value="1 0.5 0 0.4" />
+ <color
+ name="PropertyColorGroup"
+ value="0 0.72 0.72 0.4" />
+ <color
+ name="PropertyColorOther"
+ value="1 0 0 0.4" />
+ <color
+ name="PropertyColorSelf"
+ value="0 1 0 0.4" />
+ <color
+ name="ScriptBgReadOnlyColor"
+ value="0.39 0.39 0.39 1" />
+ <color
+ name="ScriptErrorColor"
+ reference="Red" />
+ <color
+ name="ScrollBGStripeColor"
+ reference="Transparent" />
+ <color
+ name="ScrollBgReadOnlyColor"
+ reference="Transparent" />
+ <color
+ name="ScrollBgWriteableColor"
+ reference="White_05" />
+ <color
+ name="ScrollDisabledColor"
+ reference="White_25" />
+ <color
+ name="ScrollHighlightedColor"
+ reference="Unused?" />
+ <color
+ name="ScrollHoveredColor"
+ reference="EmphasisColor_13" />
+ <color
+ name="ScrollSelectedBGColor"
+ reference="EmphasisColor_35" />
+ <color
+ name="ScrollSelectedFGColor"
+ reference="White" />
+ <color
+ name="ScrollUnselectedColor"
+ reference="LtGray" />
+ <color
+ name="ScrollbarThumbColor"
+ reference="White" />
+ <color
+ name="ScrollbarTrackColor"
+ reference="Black" />
+ <color
+ name="SelectedOutfitTextColor"
+ reference="EmphasisColor" />
+ <color
+ name="SilhouetteChildColor"
+ value="0.13 0.42 0.77 1" />
+ <color
+ name="SilhouetteParentColor"
+ reference="Yellow" />
+ <color
+ name="SliderDisabledThumbColor"
+ reference="White_25" />
+ <color
+ name="SliderThumbCenterColor"
+ reference="White" />
+ <color
+ name="SliderThumbOutlineColor"
+ reference="White" />
+ <color
+ name="SliderTrackColor"
+ reference="Unused?" />
+ <color
+ name="SpeakingColor"
+ reference="FrogGreen" />
+ <color
+ name="SystemChatColor"
+ reference="LtGray" />
+ <color
+ name="TextBgFocusColor"
+ reference="White" />
+ <color
+ name="TextBgReadOnlyColor"
+ reference="White_05" />
+ <color
+ name="TextBgWriteableColor"
+ reference="LtGray" />
+ <color
+ name="TextCursorColor"
+ reference="Black" />
+ <color
+ name="TextDefaultColor"
+ reference="Black" />
+ <color
+ name="TextEmbeddedItemColor"
+ value="0 0 0.5 1" />
+ <color
+ name="TextEmbeddedItemReadOnlyColor"
+ reference="Unused?" />
+ <color
+ name="TextFgColor"
+ value="0.102 0.102 0.102 1" />
+ <color
+ name="TextFgReadOnlyColor"
+ reference="LtGray" />
+ <color
+ name="TextFgTentativeColor"
+ value="0.4 0.4 0.4 1" />
+ <color
+ name="TimeTextColor"
+ reference="LtGray" />
+ <color
+ name="TitleBarFocusColor"
+ reference="White_10" />
+ <color
+ name="ToastBackground"
+ value="0.3 0.3 0.3 0" />
+ <color
+ name="ToolTipBgColor"
+ value="0.937 0.89 0.655 1" />
+ <color
+ name="ToolTipBorderColor"
+ value="0.812 0.753 0.451 1" />
+ <color
+ name="ToolTipTextColor"
+ reference="DkGray2" />
+ <color
+ name="InspectorTipTextColor"
+ reference="LtGray" />
+ <color
+ name="UserChatColor"
+ reference="White" />
+ <color
+ name="llOwnerSayChatColor"
+ reference="LtYellow" />
- <!-- New Colors -->
- <color
- name="OutputMonitorMutedColor"
- reference="DkGray2" />
- <color
- name="SysWellItemUnselected"
- value="0 0 0 0" />
- <color
- name="SysWellItemSelected"
- value="0.3 0.3 0.3 1.0" />
- <color
- name="ColorSwatchBorderColor"
- value="0.45098 0.517647 0.607843 1"/>
- <color
- name="ChatTimestampColor"
- reference="White" />
- <color
- name="MenuBarProjectBgColor"
- reference="MdBlue" />
+ <!-- New Colors -->
+ <color
+ name="OutputMonitorMutedColor"
+ reference="DkGray2" />
+ <color
+ name="SysWellItemUnselected"
+ value="0 0 0 0" />
+ <color
+ name="SysWellItemSelected"
+ value="0.3 0.3 0.3 1.0" />
+ <color
+ name="ColorSwatchBorderColor"
+ value="0.45098 0.517647 0.607843 1"/>
+ <color
+ name="ChatTimestampColor"
+ reference="White" />
+ <color
+ name="MenuBarProjectBgColor"
+ reference="MdBlue" />
- <color
+ <color
name="MeshImportTableNormalColor"
value="1 1 1 1"/>
- <color
+ <color
name="MeshImportTableHighlightColor"
value="0.2 0.8 1 1"/>
- <color
- name="DirectChatColor"
- reference="LtOrange" />
+ <color
+ name="DirectChatColor"
+ reference="LtOrange" />
- <color
+ <color
name="ToolbarDropZoneColor"
value=".48 .69 1 .5" />
- <!-- Generic color names (legacy) -->
+ <!-- Generic color names (legacy) -->
<color
- name="white"
- value="1 1 1 1"/>
+ name="white"
+ value="1 1 1 1"/>
<color
- name="black"
- value="0 0 0 1"/>
+ name="black"
+ value="0 0 0 1"/>
<color
- name="red"
- value="1 0 0 1"/>
+ name="red"
+ value="1 0 0 1"/>
<color
- name="green"
- value="0 1 0 1"/>
+ name="green"
+ value="0 1 0 1"/>
<color
- name="blue"
- value="0 0 1 1"/>
+ name="blue"
+ value="0 0 1 1"/>
</colors>
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 100644
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 100644
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/textures.xml b/indra/newview/skins/default/textures/textures.xml
index eabcc68916..06f8f8c670 100644
--- 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" />
@@ -429,6 +431,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" />
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 100644
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 100644
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/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/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index cf6f1ccdd9..33b876bdb9 100644
--- 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/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml
index 2e0f726e1a..b7cb76d4cb 100644
--- 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/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index b4c28daac9..4387a61963 100644
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -66,27 +66,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/de/floater_autoreplace.xml
new file mode 100644
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_hardware_settings.xml b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
index ca081aafae..fd6c9a0875 100644
--- 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_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_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml
index 4af8d67686..4285462bc8 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/de/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/de/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml
index 8944c79c7d..9585622516 100644
--- 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="Live-Vorschau" 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 100644
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..5f5c34a5cf 100644
--- 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."/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/de/floater_window_size.xml
index a2a53e0567..6502f002a1 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml
index 39b3099336..cd2fca313e 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml
index 412bd3ac04..9f44ced928 100644
--- a/indra/newview/skins/default/xui/de/menu_object.xml
+++ b/indra/newview/skins/default/xui/de/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="Bearbeiten" name="Edit..."/>
<menu_item_call label="Bauen" name="Build"/>
+ <menu_item_call label="In Linksets anzeigen" name="show_in_linksets"/>
+ <menu_item_call label="In Figuren anzeigen" name="show_in_characters"/>
<menu_item_call label="Öffnen" name="Open"/>
<menu_item_call label="Hier sitzen" name="Object Sit"/>
<menu_item_call label="Aufstehen" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index d011c7295c..845df1f050 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -28,6 +28,7 @@
<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">
@@ -39,6 +40,7 @@
<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_call label="Blockierliste" name="Block List"/>
</menu>
<menu label="Welt" name="World">
<menu_item_call label="Landmarke für diesen Ort setzen" name="Create Landmark Here"/>
@@ -124,6 +126,11 @@
<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>
<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"/>
@@ -174,7 +181,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 +233,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"/>
@@ -289,6 +294,12 @@
<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"/>
@@ -306,7 +317,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"/>
@@ -373,7 +383,6 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index ac068fcd4e..4b7a60b4eb 100644
--- 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"/>
@@ -367,13 +373,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 +491,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 +514,15 @@ 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="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 +619,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 +1006,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">
@@ -1162,7 +1221,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 +1240,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].
@@ -1699,83 +1757,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="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="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="Ä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 +1933,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.
@@ -2123,14 +2225,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?
@@ -2191,7 +2290,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.
@@ -2391,6 +2490,23 @@ 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="PathfindingRebakeNavmesh">
+ Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt. Um dieses Problem zu beheben, klicken Sie auf die Schaltfläche „Region neu formen“. Um weitere Informationen zu erhalten, klicken Sie auf „Hilfe“.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Hilfe" ignoretext="Wenn Sie bestimmte Objekte in dieser Region ändern, verhalten sich andere bewegliche Objekte u. U. inkorrekt." name="okhelpignore" yestext="OK"/>
+ </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 +2525,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 +2536,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 +2640,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 +2763,12 @@ 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.
+
+Eine solche Anforderung ist nur in seltenen Fällen legitim. 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="ScriptDialog">
@@ -2942,6 +3073,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 +3246,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 +3326,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/de/panel_group_invite.xml
index 5f323d80dd..c32d2fe4bf 100644
--- 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_login.xml b/indra/newview/skins/default/xui/de/panel_login.xml
index 553bd3e2ff..8cc467185c 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index 746a561e6c..c9ae350147 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/de/panel_region_debug.xml
index d1b8f0d78a..a03a0b8b7b 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/de/panel_region_estate.xml
index aecf6f62fc..b087451391 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/de/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/de/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml
index 18241dea32..1b67eaf03b 100644
--- 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..4c8d77d336 100644
--- 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>
@@ -95,6 +101,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..79cb73ecf9 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -137,7 +137,7 @@
Beenden
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=de-DE
+ http://join.secondlife.com/index.php?lang=de-DE&amp;sourceid=[sourceid]
</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:
@@ -886,6 +886,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>
@@ -919,6 +922,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="ControlYourCamera">
Kamerasteuerung
</string>
+ <string name="TeleportYourAgent">
+ Sie teleportieren
+ </string>
<string name="NotConnected">
Nicht verbunden
</string>
@@ -1000,6 +1006,9 @@ Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.
<string name="script_files">
Skripts
</string>
+ <string name="dictionary_files">
+ Wörterbücher
+ </string>
<string name="AvatarSetNotAway">
Nicht abwesend
</string>
@@ -1405,6 +1414,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 +1435,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>
@@ -3858,6 +3879,12 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_
<string name="LocationCtrlSeeAVsTooltip">
Avatare sichtbar; Chat außerhalb dieser Parzelle gestattet
</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
</string>
@@ -5000,6 +5027,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 +5057,10 @@ 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>
</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
--- 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/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 060d889003..63eb87f27a 100644
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -196,27 +196,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..793a6e6fa1 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -1354,79 +1354,13 @@ 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"
@@ -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_autoreplace.xml b/indra/newview/skins/default/xui/en/floater_autoreplace.xml
new file mode 100644
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_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 688a01ce7b..405557242f 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -46,6 +46,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/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index ca73883e53..040b66623e 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -46,7 +46,7 @@
tab_group="2"
top="0"
height="200"
- width="254"
+ width="244"
user_resize="true">
<button
height="20"
@@ -73,18 +73,20 @@
parse_highlights="true"
parse_urls="true"
left="1"
- width="249">
+ width="238">
</chat_history>
<line_editor
bottom="0"
+ left="3"
follows="left|right|bottom"
font="SansSerifSmall"
height="20"
label="To"
layout="bottomleft"
name="chat_editor"
+ spellcheck="true"
tab_group="3"
- width="249">
+ width="236">
</line_editor>
</layout_panel>
</layout_stack>
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
--- 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_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml
index 184f296255..ea44fd493e 100644
--- 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="560"
name="floater_my_inventory"
save_rect="true"
save_visibility="true"
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 100644
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 100644
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 100644
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_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml
index be3b2d179d..2e1c8ce670 100644
--- 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_spellcheck.xml b/indra/newview/skins/default/xui/en/floater_spellcheck.xml
new file mode 100644
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 100644
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 9400f7b94f..f9eb16d224 100644
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -168,7 +168,7 @@
name="texture"
label="Texture"
show_label="true">
- <stat_bar
+ <stat_bar
name="texture_cache_hits"
label="Cache Hit Rate"
stat="texture_cache_hits"
@@ -571,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"
@@ -587,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_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index ffb8b842f0..6021ba0a5a 100644
--- 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
index 44b6a63bca..1ea256b8b3 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
@@ -1,341 +1,428 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- can_minimize="false"
- height="550"
- 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_vis_http_label"
- top_delta="25"
- width="540">
- 16, Refetching visibles 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="17, 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>
- <button
- follows="left|top"
- height="20"
- label="Start"
- layout="topleft"
- left_delta="0"
- name="start_btn"
- top_delta="30"
- 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="30"
- 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="30"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.RefetchVisCache" />
- </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>
-</floater>
+<?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..5204efbf65 100644
--- 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"
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
--- 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/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml
index 63e154697b..2c420aa1e3 100644
--- 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_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index b13bf5b508..13dc0b941a 100644
--- 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">
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index 719509301b..f6004621a6 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -1,179 +1,199 @@
<?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.on_enable
+ function="EnableEdit"/>
+ </menu_item_call>
<menu_item_call
- label="Zoom In"
- name="Zoom In">
+ enabled="false"
+ label="Open"
+ name="Open">
<menu_item_call.on_click
- function="Object.ZoomIn" />
+ function="Object.Open" />
+ <menu_item_call.on_enable
+ function="Object.EnableOpen" />
</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.AttachToAvatar" />
- <menu_item_call.on_enable
- function="Object.EnableWear" />
- </menu_item_call>
- <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>
</context_menu>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index a6898c554f..18932a32d0 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -193,6 +193,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/>
@@ -291,6 +300,12 @@
function="SideTray.PanelPeopleTab"
parameter="nearby_panel" />
</menu_item_call>
+ <menu_item_call
+ label="Block List"
+ name="Block List">
+ <menu_item_call.on_click
+ function="Communicate.BlockList" />
+ </menu_item_call>
</menu>
<menu
create_jump_keys="true"
@@ -937,7 +952,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"
@@ -1374,15 +1432,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
@@ -3125,12 +3174,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">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a26c5bb344..9dae77a304 100644
--- 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
@@ -881,8 +896,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 +912,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 +1219,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
@@ -1501,6 +1530,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.
@@ -2359,6 +2396,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"
@@ -2769,7 +2893,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>
@@ -2804,12 +2928,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
@@ -4089,9 +4212,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"/>
@@ -4099,13 +4220,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>
@@ -4113,7 +4232,7 @@ 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
@@ -4121,47 +4240,156 @@ Go to the Knowledge Base for more information about maturity Ratings?
name="RegionEntryAccessBlocked_Notify"
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"
+ 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"
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"
+ 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"/>
@@ -4169,12 +4397,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
@@ -4183,41 +4442,52 @@ 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"
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"
+ 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"/>
@@ -4225,11 +4495,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">
@@ -4239,31 +4507,44 @@ 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"
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"
+ 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
@@ -4418,10 +4699,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
@@ -5127,20 +5409,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
@@ -5287,7 +5569,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>
@@ -5775,6 +6057,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"
@@ -5825,9 +6137,7 @@ You can only claim public land in the Region you&apos;re in.
persist="true"
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
@@ -5859,11 +6169,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
@@ -5872,7 +6182,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
@@ -6147,7 +6457,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
type="offer">
[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
@@ -6163,6 +6474,42 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
<notification
icon="notify.tga"
+ name="TeleportOffered_MaturityExceeded"
+ 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"
+ 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"
type="offer">
Teleport offer sent to [TO_NAME]
@@ -7197,6 +7544,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?
@@ -7679,7 +8038,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.
@@ -7738,5 +8225,31 @@ Disabling future updates for this file.
Attempted to add an invalid or unreadable image file [FNAME] which could not be opened or decoded.
Attempt cancelled.
</notification>
-
+
+ <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>
+
</notifications>
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
--- 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_group_invite.xml b/indra/newview/skins/default/xui/en/panel_group_invite.xml
index cd834b61ce..124c0596c3 100644
--- 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_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 607e1bb213..c8ce5cdebf 100644
--- 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_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index 223326dd06..134ca75018 100644
--- 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_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 21c627cdfb..6bc9c48729 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -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_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 2cc9d9c1b0..50fd57494f 100644
--- 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_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index caf7fc85f5..27193a984f 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -207,13 +207,36 @@
<button
follows="left|top"
height="23"
- label="Chat Translation Settings"
+ label="Translation..."
layout="topleft"
left="30"
name="ok_btn"
- top="-40"
+ top="-50"
width="170">
<button.commit_callback
function="Pref.TranslationSettings" />
</button>
-</panel> \ No newline at end of file
+ <button
+ follows="top|left"
+ 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
+ follows="top|left"
+ 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>
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..849f3ef73d 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -55,30 +55,57 @@
name="LowGraphicsDivet"
top_delta="-2"
width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ height="14"
+ image_name="Rounded_Square"
+ layout="topleft"
+ left_pad="41"
+ name="LowMidraphicsDivet"
+ top_delta="-2"
+ width="2" />
<icon
color="0.12 0.12 0.12 1"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="83"
+ left_pad="41"
name="MidGraphicsDivet"
top_delta="0"
width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ 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"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="85"
+ left_pad="41"
name="HighGraphicsDivet"
top_delta="0"
width="2" />
+ <icon
+ color="0.12 0.12 0.12 1"
+ 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"
height="14"
image_name="Rounded_Square"
layout="topleft"
- left_pad="83"
+ left_pad="41"
name="UltraGraphicsDivet"
top_delta="0"
width="2" />
@@ -91,7 +118,7 @@
initial_value="0"
layout="topleft"
left="120"
- max_val="3"
+ max_val="6"
name="QualityPerformanceSelection"
show_text="false"
top_delta="-2"
@@ -120,12 +147,12 @@
height="12"
layout="topleft"
left_delta="87"
- name="ShadersPrefText2"
+ name="ShadersPrefText3"
top_delta="0"
width="80">
Mid
</text>
- <text
+ <text
type="string"
length="1"
follows="left|top"
@@ -136,8 +163,8 @@
name="ShadersPrefText3"
top_delta="0"
width="80">
- High
- </text>
+ High
+ </text>
<text
type="string"
length="1"
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
--- 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_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index bfd796a62b..76a82212ae 100644
--- 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_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 3aa34439f1..dd2a0c6627 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -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_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
index 58911bed56..f5c559fe1d 100644
--- 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_volume_pulldown.xml b/indra/newview/skins/default/xui/en/panel_volume_pulldown.xml
index 7b22b2cce1..6adede0362 100644
--- 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/sidepanel_inventory.xml b/indra/newview/skins/default/xui/en/sidepanel_inventory.xml
index 6ecb57b41d..14bd349480 100644
--- 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
--- 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 bf2e6bc2d9..e69a17e037 100644
--- 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,19 +275,19 @@
<combo_box.item
label="Touch (default)"
name="Touch/grab(default)"
- value="Touch" />
+ value="Touch" />
<combo_box.item
label="Sit on object"
name="Sitonobject"
- value="Sit" />
+ value="Sit" />
<combo_box.item
label="Buy object"
name="Buyobject"
- value="Buy" />
+ value="Buy" />
<combo_box.item
label="Pay object"
name="Payobject"
- value="Pay" />
+ value="Pay" />
<combo_box.item
label="Open"
name="Open"
@@ -300,7 +308,7 @@
<text
type="string"
length="1"
- left="10"
+ left="5"
top_pad="15"
text_color="EmphasisColor"
height="15"
@@ -448,9 +456,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 866ea296c3..2157a05bbf 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -59,7 +59,7 @@
<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="LoginFailedViewerNotPermitted">
The viewer you are using can no longer access Second Life. Please visit the following page to download a new viewer:
@@ -441,6 +441,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).
@@ -671,7 +672,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)
@@ -789,9 +790,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)
@@ -1667,7 +1668,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">
@@ -1780,10 +1781,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
@@ -1872,71 +1873,202 @@ 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 -->
@@ -2140,11 +2272,15 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
<!-- 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 -->
<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>
@@ -3195,7 +3331,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<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="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
@@ -3751,6 +3888,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>
@@ -3758,4 +3902,9 @@ 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>
+
</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
--- 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/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml
index 44436fb6f2..61ec046649 100644
--- 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"
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 307b61133f..3696c7e12c 100644
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -66,27 +66,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/es/floater_autoreplace.xml
new file mode 100644
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_hardware_settings.xml b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
index b96076836b..c351db5eae 100644
--- 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="verdadero" 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_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_model_preview.xml b/indra/newview/skins/default/xui/es/floater_model_preview.xml
index ab3ba5aed7..e2313bce99 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/es/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/es/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml
index ed2787ea60..93bc9f293c 100644
--- 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="Vista previa inmediata" 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 100644
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..15462c3726 100644
--- 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."/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/es/floater_window_size.xml
index f57ce08eac..6c1ad02319 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/es/menu_inventory.xml
index 4a8f37dee4..803d3f1331 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/es/menu_object.xml
index d8c75eaf47..33ea8c88d8 100644
--- a/indra/newview/skins/default/xui/es/menu_object.xml
+++ b/indra/newview/skins/default/xui/es/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="Editar" name="Edit..."/>
<menu_item_call label="Construir" name="Build"/>
+ <menu_item_call label="Mostrar en linksets" name="show_in_linksets"/>
+ <menu_item_call label="Mostrar en personajes" name="show_in_characters"/>
<menu_item_call label="Abrir" name="Open"/>
<menu_item_call label="Sentarme aquí" name="Object Sit"/>
<menu_item_call label="Levantarme" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 9522d4eac6..d80150ef6d 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -27,6 +27,7 @@
<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">
@@ -38,6 +39,7 @@
<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_call label="Lista de ignorados" name="Block List"/>
</menu>
<menu label="Mundo" name="World">
<menu_item_call label="Crear un hito de este sitio" name="Create Landmark Here"/>
@@ -123,6 +125,11 @@
<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>
<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"/>
@@ -173,7 +180,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 +231,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"/>
@@ -270,6 +275,12 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index d47c3d7ad8..7dfb27717d 100644
--- 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"/>
@@ -357,13 +363,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 +479,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 +502,15 @@ 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="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 +611,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 +995,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">
@@ -1152,7 +1211,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 +1229,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].
@@ -1694,83 +1752,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 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 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 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 +1928,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].
@@ -2117,14 +2219,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?
@@ -2385,6 +2484,23 @@ 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="PathfindingRebakeNavmesh">
+ Si cambias ciertos objetos en esta región, otros objetos móviles podrían tener un comportamiento incorrecto. Para que los objetos móviles se comporten correctamente, pulsa el botón “Recargar la regiónâ€. Si quieres más información, elige “Ayudaâ€.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Ayuda" ignoretext="Si cambias ciertos objetos en esta región, otros objetos móviles podrían tener un comportamiento incorrecto." name="okhelpignore" yestext="OK"/>
+ </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 +2519,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 +2530,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 +2634,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 +2757,23 @@ 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 total 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, de manera permanente y sin más advertencias.
+
+Estas solicitudes pocas veces son legítimas. No autorices el acceso si no conoces la razón exacta por la que desea el acceso a tu cuenta.
<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]
- <form name="form">
- <button name="Mute" text="Ignorar"/>
- <button name="Ignore" text="Ignorar"/>
- </form>
+ <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 +3059,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 +3231,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 +3311,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/es/panel_group_invite.xml
index 0d877f78f2..319e9d0f1b 100644
--- 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_login.xml b/indra/newview/skins/default/xui/es/panel_login.xml
index 0e94cbe70b..1d7f077fe7 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index aea9b9ce4a..b0b6114e88 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/es/panel_region_debug.xml
index 64162220a6..71bdba1a25 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml
index 84c1ed7686..6089dfb8db 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/es/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/es/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/es/sidepanel_item_info.xml
index ef7c6781be..176247f90e 100644
--- 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..9da2958953 100644
--- 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>
@@ -95,6 +101,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..52bcab54e5 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -128,7 +128,7 @@
Salir
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=es-ES
+ http://join.secondlife.com/index.php?lang=es-ES&amp;sourceid=[sourceid]
</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:
@@ -871,6 +871,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 +907,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="ControlYourCamera">
Controlar su cámara
</string>
+ <string name="TeleportYourAgent">
+ Teleportarte
+ </string>
<string name="SIM_ACCESS_PG">
General
</string>
@@ -982,6 +988,9 @@ Intenta iniciar sesión de nuevo en unos instantes.
<string name="script_files">
Scripts
</string>
+ <string name="dictionary_files">
+ Diccionarios
+ </string>
<string name="AvatarSetNotAway">
Salir del estado ausente
</string>
@@ -1381,6 +1390,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 +1411,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>
@@ -3774,6 +3795,12 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].
<string name="LocationCtrlSeeAVsTooltip">
Los avatares están visibles y está permitido el chat fuera de esta parcela
</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]
</string>
@@ -4907,6 +4934,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 +4964,10 @@ 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>
</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
--- 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/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index 4409949584..a659cb4245 100644
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -66,27 +66,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 49af1a87e1..25c49b97b5 100644
--- 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">
@@ -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_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_autoreplace.xml b/indra/newview/skins/default/xui/fr/floater_autoreplace.xml
new file mode 100644
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_camera.xml b/indra/newview/skins/default/xui/fr/floater_camera.xml
index f2b0ee8af3..893e389f69 100644
--- 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_edit_day_cycle.xml b/indra/newview/skins/default/xui/fr/floater_edit_day_cycle.xml
index 0100419bc5..5ec68458e1 100644
--- 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_environment_settings.xml b/indra/newview/skins/default/xui/fr/floater_environment_settings.xml
index 9ea47a3dd7..ea12749d27 100644
--- 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_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml
index e4c53d866c..0d21a8af32 100644
--- 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_hardware_settings.xml b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
index 2bc76e0c63..098f8fc713 100644
--- 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="vraie" 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_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_land_holdings.xml b/indra/newview/skins/default/xui/fr/floater_land_holdings.xml
index 10fe132623..ff728e3aaa 100644
--- 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_model_preview.xml b/indra/newview/skins/default/xui/fr/floater_model_preview.xml
index a3b50351ae..bd3dae6599 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/fr/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_preview_animation.xml b/indra/newview/skins/default/xui/fr/floater_preview_animation.xml
index f2cb1d5e70..6488089c06 100644
--- 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_spellcheck.xml b/indra/newview/skins/default/xui/fr/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml
index 381bcceb00..f86c1a4217 100644
--- 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="Aperçu direct" 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 100644
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..bcc3423862 100644
--- 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."/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/fr/floater_window_size.xml
index cbda4390d8..11c2e439bd 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml
index 59dcff9075..627d3068c3 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/fr/menu_object.xml
index c6db48a31c..573b6da582 100644
--- a/indra/newview/skins/default/xui/fr/menu_object.xml
+++ b/indra/newview/skins/default/xui/fr/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="Modifier" name="Edit..."/>
<menu_item_call label="Construire" name="Build"/>
+ <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"/>
<menu_item_call label="Ouvrir" name="Open"/>
<menu_item_call label="M&apos;asseoir ici" name="Object Sit"/>
<menu_item_call label="Me lever" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 3c3d4f5f69..85020afe25 100644
--- 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"/>
@@ -28,6 +28,7 @@
<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">
@@ -39,6 +40,7 @@
<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_call label="Liste des ignorés" name="Block List"/>
</menu>
<menu label="Monde" name="World">
<menu_item_call label="Créer un repère pour ce lieu" name="Create Landmark Here"/>
@@ -124,6 +126,11 @@
<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>
<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"/>
@@ -171,10 +178,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 +233,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"/>
@@ -289,6 +294,12 @@
<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"/>
@@ -306,7 +317,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"/>
@@ -373,7 +383,6 @@
<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_item_call label="Forcer les paramètres par défaut" name="Force Params to Default"/>
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 746a4b1d55..30154d1873 100644
--- 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"/>
@@ -359,13 +365,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 +484,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 +506,15 @@ 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="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 +611,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 +994,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">
@@ -1143,7 +1202,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 +1221,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 +1363,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">
@@ -1684,83 +1742,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="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 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 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 +1918,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.
@@ -2108,14 +2210,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 ?
@@ -2377,6 +2476,23 @@ 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="PathfindingRebakeNavmesh">
+ La modification de certains objets de cette région risque d&apos;entraîner un comportement incorrect des autres objets mobiles. Pour que les objets mobiles se comportent correctement, cliquez sur Refiger la région. Pour plus d&apos;informations, choisissez Aide.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Aide" ignoretext="La modification de certains objets de cette région risque d&apos;entraîner un comportement incorrect des autres objets mobiles." name="okhelpignore" yestext="OK"/>
+ </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 +2511,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 +2522,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 +2628,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 +2749,12 @@ 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.
+
+Il est rare qu&apos;une telle demande soit légitime. 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="ScriptDialog">
@@ -2927,6 +3058,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 +3233,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 +3313,23 @@ 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>
</notifications>
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..96add2a74b 100644
--- a/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/fr/panel_block_list_sidetray.xml
@@ -5,6 +5,6 @@
</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="Ignorer un objet par son nom" label_selected="Ignorer un objet par son 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>
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_group_invite.xml b/indra/newview/skins/default/xui/fr/panel_group_invite.xml
index 53f7ac33c2..d792439220 100644
--- 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_login.xml b/indra/newview/skins/default/xui/fr/panel_login.xml
index e54b36644c..c8a1fe8751 100644
--- 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_postcard_settings.xml b/indra/newview/skins/default/xui/fr/panel_postcard_settings.xml
index 6f4e9c23f9..945a5e0272 100644
--- 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_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 76ed237451..550beb653e 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_move.xml b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
index 94d7322b22..80aed90a2d 100644
--- 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_region_debug.xml b/indra/newview/skins/default/xui/fr/panel_region_debug.xml
index 733c3f9a22..98ae250215 100644
--- 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
--- 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
--- 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
--- 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
--- 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_question_toast.xml b/indra/newview/skins/default/xui/fr/panel_script_question_toast.xml
new file mode 100644
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_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_snapshot_inventory.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_inventory.xml
index 4454d2475e..472c4a5e8f 100644
--- 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
--- 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
--- 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
--- 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_volume_pulldown.xml b/indra/newview/skins/default/xui/fr/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/fr/sidepanel_item_info.xml
index 95649d3934..e7fc7859c9 100644
--- 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..60027d41cb 100644
--- 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>
@@ -95,6 +101,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 8b410128da..6a2a3f559a 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -137,7 +137,7 @@
Quitter
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=fr-FR
+ http://join.secondlife.com/index.php?lang=fr-FR&amp;sourceid=[sourceid]
</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 :
@@ -886,6 +886,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>
@@ -919,6 +922,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="ControlYourCamera">
Contrôler votre caméra
</string>
+ <string name="TeleportYourAgent">
+ Vous téléporter
+ </string>
<string name="NotConnected">
Pas connecté(e)
</string>
@@ -1000,6 +1006,9 @@ Veuillez réessayer de vous connecter dans une minute.
<string name="script_files">
Scripts
</string>
+ <string name="dictionary_files">
+ Dictionnaires
+ </string>
<string name="AvatarSetNotAway">
Présent
</string>
@@ -1405,6 +1414,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 +1435,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>
@@ -3858,6 +3879,12 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
<string name="LocationCtrlSeeAVsTooltip">
Avatars visibles et chat autorisé en dehors de cette parcelle
</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
</string>
@@ -4887,7 +4914,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
@@ -5000,6 +5027,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 +5057,10 @@ 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>
</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
--- 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/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index 39114b7bf7..c672511fc5 100644
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -66,27 +66,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/it/floater_autoreplace.xml
new file mode 100644
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_hardware_settings.xml b/indra/newview/skins/default/xui/it/floater_hardware_settings.xml
index 5d3ae04a4d..edbbc354cf 100644
--- 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_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_model_preview.xml b/indra/newview/skins/default/xui/it/floater_model_preview.xml
index ca36fd2def..e8df4d2d4b 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/it/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/it/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml
index 7b77584ba0..c97a91bb3f 100644
--- 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="Anteprima dal vivo" 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 100644
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..dd59035dd4 100644
--- 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."/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/it/floater_window_size.xml
index 036b74b7d9..fef423aefe 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml
index 4bf6be82fd..b31e35771d 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml
index a172cf3b26..7f41e8937f 100644
--- a/indra/newview/skins/default/xui/it/menu_object.xml
+++ b/indra/newview/skins/default/xui/it/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="Modifica" name="Edit..."/>
<menu_item_call label="Costruisci" name="Build"/>
+ <menu_item_call label="Mostra nei set collegati" name="show_in_linksets"/>
+ <menu_item_call label="Mostra nei personaggi" name="show_in_characters"/>
<menu_item_call label="Apri" name="Open"/>
<menu_item_call label="Siediti qui" name="Object Sit"/>
<menu_item_call label="Alzati" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml
index 99b7e3c4e6..547c5a9b73 100644
--- a/indra/newview/skins/default/xui/it/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/it/menu_viewer.xml
@@ -28,6 +28,7 @@
<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">
@@ -39,6 +40,7 @@
<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_call label="Blocca lista" name="Block List"/>
</menu>
<menu label="Mondo" name="World">
<menu_item_call label="Crea punto di riferimento per questo luogo" name="Create Landmark Here"/>
@@ -124,6 +126,11 @@
<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>
<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"/>
@@ -174,7 +181,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 +232,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"/>
@@ -271,6 +276,12 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 0e6fee60d1..d5fdde4e7d 100644
--- 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"/>
@@ -360,13 +366,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 +504,15 @@ 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="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 +610,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 +992,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">
@@ -1148,7 +1207,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 +1226,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].
@@ -1689,83 +1747,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 +1923,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].
@@ -2114,14 +2216,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?
@@ -2382,6 +2481,23 @@ 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="PathfindingRebakeNavmesh">
+ Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento. Per fare in modo che gli oggetti in movimento si comportino correttamente, fai clic sul pulsante &quot;Rebake regione&quot;. Per maggiori informazioni, seleziona la guida
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Guida" ignoretext="Se modifichi alcuni oggetti in questa regione, ciò potrebbe causare il comportamento errato di altri oggetti in movimento." name="okhelpignore" yestext="OK"/>
+ </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 +2516,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 +2527,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 +2633,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 +2754,12 @@ 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?
+ Attenzione: 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 qalunque momento e anche svuotare completamente l&apos;account, per un periodo illimitato e senza ulteriori avvisi.
+
+Raramente questo tipo di richiesta è legittima. 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="ScriptDialog">
@@ -2929,6 +3063,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 +3238,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 +3318,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/it/panel_group_invite.xml
index e3cb3c1092..1b57eba3f0 100644
--- 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_login.xml b/indra/newview/skins/default/xui/it/panel_login.xml
index f88230ed11..2afde40940 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
index 7f5992b584..0c9c4027e5 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/it/panel_region_debug.xml
index 45b3a016f4..aba60d03aa 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/it/panel_region_estate.xml
index da6b6b277f..98d9b86cfc 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/it/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/it/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml
index 900a65956b..2b3ea0fb83 100644
--- 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..8a0f93e650 100644
--- 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>
@@ -95,6 +101,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..fb1e387468 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -134,7 +134,7 @@
Esci
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=it-IT
+ http://join.secondlife.com/index.php?lang=it-IT&amp;sourceid=[sourceid]
</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:
@@ -880,6 +880,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 +916,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="ControlYourCamera">
Controllare la tua fotocamera
</string>
+ <string name="TeleportYourAgent">
+ Teleportarti
+ </string>
<string name="SIM_ACCESS_PG">
Generale
</string>
@@ -991,6 +997,9 @@ Prova ad accedere nuovamente tra un minuto.
<string name="script_files">
Script
</string>
+ <string name="dictionary_files">
+ Dizionari
+ </string>
<string name="AvatarSetNotAway">
Imposta come non assente
</string>
@@ -1390,6 +1399,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 +1420,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>
@@ -3780,6 +3801,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
<string name="LocationCtrlSeeAVsTooltip">
Avatar visibili e chat consentita fuori di questo 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]
</string>
@@ -4910,6 +4937,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 +4967,10 @@ 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>
</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
--- 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..6d5df75645 100644
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -66,27 +66,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/ja/floater_autoreplace.xml
new file mode 100644
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_hardware_settings.xml b/indra/newview/skins/default/xui/ja/floater_hardware_settings.xml
index 1b6558a9eb..c8b8e918e0 100644
--- 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_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_model_preview.xml b/indra/newview/skins/default/xui/ja/floater_model_preview.xml
index c9ff0e29cb..942cc91317 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/ja/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/ja/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml
index 399cffcce5..3773812bb6 100644
--- 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 100644
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..4bd6439ad2 100644
--- 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="オブジェクトã®ç§»å‹•ã¨å‰Šé™¤ã‚’ç¦æ­¢ã—ã¾ã™ã€‚ ã“ã®æ©Ÿèƒ½ã‚’使ã†ã¨ã€åˆ¶ä½œä¸­ã®æ„図ã›ã¬ç·¨é›†ã‚’防ãã“ã¨ãŒã§ãã¾ã™"/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/ja/floater_window_size.xml
index 152a5f4806..416813d6cc 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/ja/menu_inventory.xml
index d1893a0fc8..106b09453a 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml
index 4cee8089ee..01436ad12b 100644
--- a/indra/newview/skins/default/xui/ja/menu_object.xml
+++ b/indra/newview/skins/default/xui/ja/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="編集" name="Edit..."/>
<menu_item_call label="制作" name="Build"/>
+ <menu_item_call label="リンクセットã§è¡¨ç¤º" name="show_in_linksets"/>
+ <menu_item_call label="キャラクターã§è¡¨ç¤º" name="show_in_characters"/>
<menu_item_call label="é–‹ã" name="Open"/>
<menu_item_call label="ã“ã“ã«åº§ã‚‹" name="Object Sit"/>
<menu_item_call label="ç«‹ã¡ä¸ŠãŒã‚‹" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/ja/menu_viewer.xml
index 8496dfb1db..e60e6781c6 100644
--- a/indra/newview/skins/default/xui/ja/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml
@@ -28,6 +28,7 @@
<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">
@@ -39,6 +40,7 @@
<menu_item_call label="フレンド" name="My Friends"/>
<menu_item_call label="グループ" name="My Groups"/>
<menu_item_call label="è¿‘ãã«ã„る人" name="Active Speakers"/>
+ <menu_item_call label="リストをブロック" name="Block List"/>
</menu>
<menu label="世界" name="World">
<menu_item_call label="ç¾åœ¨åœ°ã‚’ランドマーク" name="Create Landmark Here"/>
@@ -124,6 +126,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"/>
@@ -174,7 +181,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 +233,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"/>
@@ -289,6 +294,12 @@
<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"/>
@@ -306,7 +317,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"/>
@@ -373,7 +383,6 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 7bf8a7b8be..d5cff18a24 100644
--- 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"/>
@@ -382,13 +388,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 +507,7 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
</notification>
<notification name="StartRegionEmpty">
ログインä½ç½®ãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。
-ログインä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œãƒ›ãƒ¼ãƒ ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。
+ログインä½ç½®ã®æ¬„ã«ãƒªãƒ¼ã‚¸ãƒ§ãƒ³åを入力ã™ã‚‹ã‹ã€ã€Œæœ€å¾Œã«ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ãŸå ´æ‰€ã€ã‹ã€Œè‡ªå®…(ホーム)ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -517,6 +529,15 @@ 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="UnknownGPU">
ãŠä½¿ã„ã®ã‚·ã‚¹ãƒ†ãƒ ã«ã¯ã€[APP_NAME] ãŒèªè­˜ã§ããªã„グラフィックカードãŒæ­è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚
[APP_NAME] ã§ã¾ã ãƒ†ã‚¹ãƒˆã•ã‚Œã¦ã„ãªã„最新ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ã®ãŸã‚ã ã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚ å•é¡Œãªã„ã¨ã¯æ€ã„ã¾ã™ãŒã€ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã®è¨­å®šã‚’調整ã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。
@@ -614,6 +635,9 @@ L$ ãŒä¸è¶³ã—ã¦ã„ã‚‹ã®ã§ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã«å‚加ã™ã‚‹ã“ã¨ãŒã§ãã
ã©ã®ã‚ªãƒ–ジェクトもロックã•ã‚Œã¦ãŠã‚‰ãšã€ã‚ãªãŸã®ã‚‚ã®ã§ã‚ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。
</notification>
+ <notification name="CannotLinkPermanent">
+ 地域(リージョン)ã®å¢ƒç•Œã‚’越ãˆã¦ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。
+ </notification>
<notification name="CannotLinkDifferentOwners">
所有者ãŒç•°ãªã‚‹ãŸã‚ã€ã‚ªãƒ–ジェクトをリンクã§ãã¾ã›ã‚“。
@@ -1000,6 +1024,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">
@@ -1182,7 +1240,7 @@ L$ ã¯è¿”金ã•ã‚Œã¾ã›ã‚“。
è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚
</notification>
<notification name="AvatarMovedLast">
- å‰å›žã„ãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。
+ リクエストã•ã‚ŒãŸå ´æ‰€ã¯ç¾åœ¨ã”利用ã„ãŸã ã‘ã¾ã›ã‚“。
è¿‘ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ç§»å‹•ã—ã¾ã—ãŸã€‚
</notification>
<notification name="AvatarMovedHome">
@@ -1201,8 +1259,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] ã®å•é¡Œã¨è€ƒãˆã‚‰ã‚Œã¾ã™ã€‚
@@ -1724,83 +1781,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="é¸æŠžã—ãŸãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒåŽŸå› ã§ã€ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚Œãªã„ã¨ã"/>
+ <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 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 +1960,9 @@ L$ [AMOUNT] ã§ã€ã“ã®ã‚¯ãƒ©ã‚·ãƒ•ã‚¡ã‚¤ãƒ‰åºƒå‘Šã‚’今ã™ã公開ã—ã¾ã™ã
</form>
</notification>
<notification label="地域ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†æŒ‡å®šå¤‰æ›´æ¸ˆã¿" name="RegionMaturityChange">
- ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼ˆåœ°åŸŸï¼‰ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒã‚¢ãƒƒãƒ—デートã•ã‚Œã¾ã—ãŸã€‚
-地図ã«å¤‰æ›´ãŒå映ã•ã‚Œã‚‹ã¾ã§æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
-
-Adult 専用リージョンã«å…¥ã‚‹ã«ã¯ã€ä½äººã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆãŒå¹´é½¢ç¢ºèªã‹æ”¯æ‰•æ–¹æ³•ã®ã„ãšã‚Œã‹ã§ã€Œç¢ºèªæ¸ˆã¿ã€ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+ ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ãŒå¤‰æ›´ã•ã‚Œã¾ã—ãŸã€‚
+地図ã«ã“ã®å¤‰æ›´ãŒå映ã™ã‚‹ã«ã¯æ•°åˆ†ã‹ã‹ã‚‹ã“ã¨ãŒã‚ã‚Šã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification label="ボイスãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´" name="VoiceVersionMismatch">
[APP_NAME] ã®ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã€ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ãŠã‘るボイスãƒãƒ£ãƒƒãƒˆã®äº’æ›æ€§ãŒã‚ã‚Šã¾ã›ã‚“。 ボイスãƒãƒ£ãƒƒãƒˆã‚’正常ã«è¡Œã†ãŸã‚ã«ã¯ã€[APP_NAME] ã®ã‚¢ãƒƒãƒ—デートãŒå¿…è¦ã§ã™ã€‚
@@ -2156,14 +2257,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] サイトã§ç™»éŒ²ã‚’è¡Œã„ã¾ã™ã‹ï¼Ÿ
@@ -2426,6 +2524,23 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="NoBuild">
ã“ã®ã‚¨ãƒªã‚¢ã§ã¯åˆ¶ä½œãŒç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚ オブジェクトを制作ã—ãŸã‚Š Rez ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
</notification>
+ <notification name="PathfindingDirty">
+ ã“ã®å€¤åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«ã¯ã€ä¿ç•™ä¸­ã®ãƒ‘スファインディングã®å¤‰æ›´ãŒã‚ã‚Šã¾ã™ã€‚制作権ãŒã‚ã‚‹å ´åˆã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¦ã€åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’å†æ§‹ç¯‰ã§ãã¾ã™ã€‚
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘スファインディングãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。パスファインディング LSL 呼ã³å‡ºã—を使用ã™ã‚‹ã‚¹ã‚¯ãƒªãƒ—ト化ã•ã‚ŒãŸã‚ªãƒ–ジェクトãŒã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ã¯å‹•ä½œã§ãã¾ã›ã‚“。
+ </notification>
+ <notification name="PathfindingRebakeNavmesh">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹ã¨ã€ä»–ã®ç§»å‹•ã‚ªãƒ–ジェクトãŒæ­£ã—ã動作ã—ãªããªã‚‹æã‚ŒãŒã‚ã‚Šã¾ã™ã€‚移動オブジェクトを正ã—ã動作ã•ã›ã‚‹ã«ã¯ã€ã€Œåœ°åŸŸã®å†æ§‹ç¯‰ã€ãƒœã‚¿ãƒ³ã‚’クリックã—ã¾ã™ã€‚詳ã—ã„情報ã¯è¦‹ã‚‹ã«ã¯ã€Œãƒ˜ãƒ«ãƒ—ã€ã‚’é¸æŠžã—ã¦ãã ã•ã„。
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="ヘルプ" ignoretext="ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã®ã‚ªãƒ–ジェクトを変更ã™ã‚‹ã¨ã€ä»–ã®ç§»å‹•ã‚ªãƒ–ジェクトãŒæ­£ã—ã動作ã—ãªããªã‚‹æã‚ŒãŒã‚ã‚Šã¾ã™ã€‚" name="okhelpignore" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã¾ãŸã¯ã‚µãƒ¼ãƒãƒ¼ã«å•é¡ŒãŒã‚ã‚‹ã‹ã€åˆ¶ä½œæ¨©ãŒãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã“ã®å•é¡Œã¯ã€ä¸€åº¦ãƒ­ã‚°ã‚¢ã‚¦ãƒˆã—ã¦ã‹ã‚‰ã€ãƒ­ã‚°ã‚¤ãƒ³ã—ç›´ã™ã¨è§£æ±ºã•ã‚Œã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
ã“ã®åŒºç”»ã«ã„ã‚‹ã‚¢ãƒã‚¿ãƒ¼ã‚„ã“ã®åŒºç”»å†…ã§è¡Œã‚れる文字ãƒãƒ£ãƒƒãƒˆã¯ã€ä»–ã®åŒºç”»ã‹ã‚‰è¦‹ãˆã¾ã›ã‚“。ã‚ãªãŸã«ã¯ã€ã“ã®åŒºç”»å¤–ã«ã„ã‚‹ä½äººãŒè¦‹ãˆãšã€å¤–ã®ä½äººã«ã¯ã‚ãªãŸã®å§¿ãŒè¦‹ãˆã¾ã›ã‚“。ãƒãƒ£ãƒ³ãƒãƒ« 0 ã§ã®é€šå¸¸ã®æ–‡å­—ãƒãƒ£ãƒƒãƒˆã‚‚ブロックã•ã‚Œã¾ã™ã€‚
</notification>
@@ -2444,9 +2559,7 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
ãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«ã„ãªã„ã¨å…¬å…±ã®åœŸåœ°ã‚’å–å¾—ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。
</notification>
<notification name="RegionTPAccessBlocked">
- ã‚ãªãŸã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã«ã‚ˆã‚Šãã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã¯å…¥ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 年齢確èªã‚’è¡Œã†ã‹ã€æœ€æ–°ãƒ“ューワをインストールã—ã¦ãã ã•ã„。
-
-ç¾åœ¨ã®ãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°åŒºåˆ†ã§ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªã‚¨ãƒªã‚¢ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒŠãƒ¬ãƒƒã‚¸ãƒ™ãƒ¼ã‚¹ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
+ 訪å•ã—よã†ã¨ã—ã¦ã„る地域(リージョン)ã«ã¯ç¾åœ¨ã®ç’°å¢ƒè¨­å®šã‚’超ãˆã‚‹ã‚³ãƒ³ãƒ†ãƒ³ãƒ„ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚「ミー〠&gt; 「環境設定〠&gt; 「一般ã€ã‚’é¸æŠžã—ã¦ã€ç’°å¢ƒè¨­å®šã‚’変更ã§ãã¾ã™ã€‚
</notification>
<notification name="URBannedFromRegion">
ã‚ãªãŸã¯ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã¸ã®ç«‹å…¥ãŒç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚
@@ -2457,11 +2570,11 @@ Web ページã«ãƒªãƒ³ã‚¯ã™ã‚‹ã¨ã€ä»–人ãŒã“ã®å ´æ‰€ã«ç°¡å˜ã«ã‚¢ã‚¯ã‚»ã
<notification name="ImproperPaymentStatus">
ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«é©ã—ãŸæ”¯æ‰•ã„ステータスãŒã‚ã‚Šã¾ã›ã‚“。
</notification>
- <notification name="MustGetAgeRgion">
- ã“ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ <notification name="MustGetAgeRegion">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
</notification>
<notification name="MustGetAgeParcel">
- ã“ã®åŒºç”»ã«å…¥ã‚‹ãŸã‚ã«ã¯ã€å¹´é½¢ç¢ºèªã‚’済ã¾ã›ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ ã“ã®åŒºç”»ã«å…¥ã‚‹ã«ã¯ 18 æ‰ä»¥ä¸Šã§ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
</notification>
<notification name="NoDestRegion">
目的地ã®ãƒªãƒ¼ã‚¸ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚
@@ -2563,12 +2676,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 +2797,12 @@ 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="ScriptDialog">
@@ -2895,18 +3025,6 @@ M キーを押ã—ã¦å¤‰æ›´ã—ã¾ã™ã€‚
[RESIDENTS]
<usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="Ok"/>
</notification>
- <notification name="ShareFolderConfirmation">
- フォルダã¯ä¸€åº¦ã« 1 ã¤ã—ã‹å…±æœ‰ã§ãã¾ã›ã‚“。
-
-次ã®ã‚¢ã‚¤ãƒ†ãƒ ã‚’共有ã—ã¾ã™ã‹ï¼Ÿ
-
-&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
-
-次ã®ä½äººã¨å…±æœ‰ï¼š
-
-[RESIDENTS]
- <usetemplate name="okcancelbuttons" notext="å–り消ã—" yestext="Ok"/>
- </notification>
<notification name="ItemsShared">
アイテムãŒå…±æœ‰ã•ã‚Œã¾ã—ãŸã€‚
</notification>
@@ -2985,6 +3103,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="ã¯ã„"/>
@@ -3156,6 +3278,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 グラフィックカードãŒå¿…è¦ã§ã™ã€‚ ãŠä½¿ã„ã®ã‚°ãƒ©ãƒ•ã‚£ãƒƒã‚¯ã‚«ãƒ¼ãƒ‰ã®æœ€æ–°ãƒ‰ãƒ©ã‚¤ãƒãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã‚‹ã‹ã©ã†ã‹ã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã®ã‚µãƒ¼ãƒ“スパックã¨ãƒ‘ッãƒãŒå…¥ã£ã¦ã„ã‚‹ã‹ã‚’ã”確èªãã ã•ã„。
@@ -3180,4 +3358,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/ja/panel_group_invite.xml
index a21b340fdd..cc9ebc405b 100644
--- 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_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml
index ac1fe455c7..396d9e65b1 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
index 75bf28a3c8..b6e344ca48 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/ja/panel_region_debug.xml
index f6865c12b1..169da27ce5 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml
index 2e58c5a8f1..b5cc6b9765 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/ja/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/ja/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml
index 6931e448b3..e70d91d258 100644
--- 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..c61c73657f 100644
--- 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>
@@ -95,6 +101,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..50697e5500 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -137,7 +137,7 @@
終了
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=ja-JP
+ http://join.secondlife.com/index.php?lang=ja-JP&amp;sourceid=[sourceid]
</string>
<string name="LoginFailedViewerNotPermitted">
ãŠä½¿ã„ã®å¤ã„ビューワã§ã¯ Second Life ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“。以下ã®ãƒšãƒ¼ã‚¸ã‹ã‚‰æ–°ã—ã„ビューワをダウンロードã—ã¦ãã ã•ã„:
@@ -886,6 +886,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ScriptQuestionCautionChatDenied">
[REGIONNAME] ã® [REGIONPOS] ã¨ã„ã†å ´æ‰€ã«ã‚ã‚‹ã€ã€Œ [OWNERNAME] ã€ãŒæ‰€æœ‰ã™ã‚‹ã€Œ [OBJECTNAME] ã€ã¨ã„ã†ã‚ªãƒ–ジェクトã¯ã€æ¬¡ã®æ¨©é™ã‚’æ‹’å¦ã—ã¾ã—ãŸï¼š [PERMISSIONS]
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ ã‚ãªãŸã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã‚’許å¯ã™ã‚‹ã¨ã€ã“ã®ã‚ªãƒ–ジェクトã«ã¯æ¬¡ã®æ“作も許å¯ã•ã‚Œã¾ã™ï¼š
+ </string>
<string name="ScriptTakeMoney">
リンデンドル(L$)を支払ã†
</string>
@@ -919,6 +922,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="ControlYourCamera">
カメラã®ã‚³ãƒ³ãƒˆãƒ­ãƒ¼ãƒ«
</string>
+ <string name="TeleportYourAgent">
+ ã‚ãªãŸã‚’テレãƒãƒ¼ãƒˆ
+ </string>
<string name="NotConnected">
接続ã•ã‚Œã¦ã„ã¾ã›ã‚“
</string>
@@ -1000,6 +1006,9 @@ support@secondlife.com ã«ãŠå•ã„åˆã‚ã›ãã ã•ã„。
<string name="script_files">
スクリプト
</string>
+ <string name="dictionary_files">
+ 辞書
+ </string>
<string name="AvatarSetNotAway">
一時退席中解除
</string>
@@ -1405,6 +1414,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 +1435,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>
@@ -3858,6 +3879,12 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="LocationCtrlSeeAVsTooltip">
ã“ã®åŒºç”»å¤–ã«ã‚¢ãƒã‚¿ãƒ¼ã‚’見ãˆã‚‹ã‚ˆã†ã«ã—ã¦ã€ãƒãƒ£ãƒƒãƒˆã‚‚許å¯
</string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ 地域(リージョン)ãŒå†æ§‹ç¯‰ã•ã‚Œã‚‹ã¾ã§ã€ç§»å‹•ã™ã‚‹ã‚ªãƒ–ジェクトã¯æ­£ã—ã動作ã—ãªã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã§ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ‘スファインディングãŒæœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã›ã‚“。
+ </string>
<string name="UpdaterWindowTitle">
[APP_NAME] アップデート
</string>
@@ -5000,6 +5027,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 +5057,10 @@ www.secondlife.com ã‹ã‚‰æœ€æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’ダウンロードã—ã¦ãã ã
<string name="snapshot_quality_very_high">
éžå¸¸ã«é«˜ã„
</string>
+ <string name="TeleportMaturityExceeded">
+ ä½äººã¯ã“ã®åœ°åŸŸï¼ˆãƒªãƒ¼ã‚¸ãƒ§ãƒ³ï¼‰ã‚’訪å•ã§ãã¾ã›ã‚“。
+ </string>
+ <string name="UserDictionary">
+ [User]
+ </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
--- 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/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index 0194293642..f255b1b8ea 100644
--- 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/panel_login.xml b/indra/newview/skins/default/xui/pl/panel_login.xml
index dc8e7399af..c87a3d3bd4 100644
--- 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_volume_pulldown.xml b/indra/newview/skins/default/xui/pl/panel_volume_pulldown.xml
new file mode 100644
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/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index e843e56090..299f88b22a 100644
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -65,27 +65,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/pt/floater_autoreplace.xml
new file mode 100644
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_hardware_settings.xml b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
index 1bc2bce768..1204fb93e2 100644
--- 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_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_model_preview.xml b/indra/newview/skins/default/xui/pt/floater_model_preview.xml
index 8960500831..8194278b16 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/pt/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/pt/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml
index 144bc0340e..a75cf34a94 100644
--- 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="Visualização em tempo real" 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 100644
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..8c245c582e 100644
--- 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."/>
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
--- 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_window_size.xml b/indra/newview/skins/default/xui/pt/floater_window_size.xml
index 6a8ccbd002..7deb799bd7 100644
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml
index 09e1fbf72e..a3a648eb34 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/pt/menu_object.xml
index f4919e0c1f..28dd9febe2 100644
--- a/indra/newview/skins/default/xui/pt/menu_object.xml
+++ b/indra/newview/skins/default/xui/pt/menu_object.xml
@@ -5,6 +5,8 @@
</menu_item_call>
<menu_item_call label="Editar" name="Edit..."/>
<menu_item_call label="Construir" name="Build"/>
+ <menu_item_call label="Exibir em linksets" name="show_in_linksets"/>
+ <menu_item_call label="Exibir em personagens" name="show_in_characters"/>
<menu_item_call label="Abrir" name="Open"/>
<menu_item_call label="Sentar aqui" name="Object Sit"/>
<menu_item_call label="Ficar de pé" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index fd973bf3c2..ca378c1b58 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -28,6 +28,7 @@
<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">
@@ -39,6 +40,7 @@
<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_call label="Lista de bloqueados" name="Block List"/>
</menu>
<menu label="Mundo" name="World">
<menu_item_call label="Criar marco deste lugar" name="Create Landmark Here"/>
@@ -124,6 +126,11 @@
<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>
<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"/>
@@ -174,7 +181,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 +232,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"/>
@@ -271,6 +276,12 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 3b39c0f92c..ff7382bf80 100644
--- 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"/>
@@ -357,13 +363,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 +478,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 +501,15 @@ 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="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 +606,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 +987,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">
@@ -1137,7 +1196,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 +1212,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].
@@ -1673,83 +1731,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ê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 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ê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 +1907,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].
@@ -2097,14 +2199,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?
@@ -2362,6 +2461,23 @@ 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="PathfindingRebakeNavmesh">
+ A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento. Para fazer com que os objetos em movimento se comportem corretamente, clique no botão “Recarregar regiãoâ€. Escolha “Ajuda†para obter mais informações.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Ajuda" ignoretext="A alteração de determinados objetos nesta região pode resultar no comportamento incorreto de outros objeto em movimento." name="okhelpignore" yestext="OK"/>
+ </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 +2496,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 +2507,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 +2613,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 +2734,12 @@ 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.
+
+Esse tipo de pedido raramente é legítimo. 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="ScriptDialog">
@@ -2903,6 +3037,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 +3210,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 +3290,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/pt/panel_group_invite.xml
index c7def0ed96..de057481de 100644
--- 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_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml
index f4af6a7108..d7e9fa76ea 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index c5a4febb0e..350d53b81c 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/pt/panel_region_debug.xml
index f2cc9f644d..be15d40d74 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/pt/panel_region_estate.xml
index 6c5945aa15..b1453c9c32 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/pt/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/pt/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/pt/sidepanel_item_info.xml
index e6370ea830..d3cb087108 100644
--- 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..3cfe0fe4f4 100644
--- 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>
@@ -95,6 +101,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..bc72b86020 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -128,7 +128,7 @@
Sair
</string>
<string name="create_account_url">
- http://join.secondlife.com/index.php?lang=pt-BR
+ http://join.secondlife.com/index.php?lang=pt-BR&amp;sourceid=[sourceid]
</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
@@ -835,6 +835,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 +871,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="ControlYourCamera">
Controle sua camera
</string>
+ <string name="TeleportYourAgent">
+ Teletransportá-lo
+ </string>
<string name="SIM_ACCESS_PG">
Público geral
</string>
@@ -946,6 +952,9 @@ Pessoas com contas gratuitas não poderão acessar o Second Life no momento para
<string name="script_files">
Scripts
</string>
+ <string name="dictionary_files">
+ Dicionários
+ </string>
<string name="AvatarSetNotAway">
deixar como ausente
</string>
@@ -1345,6 +1354,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 +1375,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>
@@ -3734,6 +3755,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="LocationCtrlSeeAVsTooltip">
Avatar visíveis e bate-papo permitido fora deste terreno
</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
</string>
@@ -4867,6 +4894,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 +4924,10 @@ 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>
</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
--- 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/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index 119f104906..bb6266ac9a 100644
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -62,27 +62,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/ru/floater_autoreplace.xml
new file mode 100644
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_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_hardware_settings.xml b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
index 7400f1df3b..43f8c36473 100644
--- a/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/ru/floater_hardware_settings.xml
@@ -25,6 +25,10 @@
Включить VBO:
</text>
<check_box initial_value="иÑтина" 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_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_model_preview.xml b/indra/newview/skins/default/xui/ru/floater_model_preview.xml
index 5bb96b8de4..0c6d41b4ef 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/ru/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/ru/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml
index d55daea836..db37089aeb 100644
--- 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="иÑтина" 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"/>
+ <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 100644
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..c312f73428 100644
--- a/indra/newview/skins/default/xui/ru/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ru/floater_tools.xml
@@ -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="Предотвращение Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°. Обычно Ñта Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð° во Ð²Ñ€ÐµÐ¼Ñ Ñтройки Ð´Ð»Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°Ð½Ð¸Ñ Ð½ÐµÐ¶ÐµÐ»Ð°Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ñ… изменений."/>
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
--- 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_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_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
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml
index 49f7281b4e..37ee19fc1d 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/ru/menu_object.xml
index d6abfd12a2..288df3beb9 100644
--- a/indra/newview/skins/default/xui/ru/menu_object.xml
+++ b/indra/newview/skins/default/xui/ru/menu_object.xml
@@ -3,6 +3,8 @@
<menu_item_call label="КоÑнутьÑÑ" name="Object Touch"/>
<menu_item_call label="Изменить" name="Edit..."/>
<menu_item_call label="СтроительÑтво" name="Build"/>
+ <menu_item_call label="Показывать в наборах ÑвÑзей" name="show_in_linksets"/>
+ <menu_item_call label="Показывать в перÑонажах" name="show_in_characters"/>
<menu_item_call label="Открыто" name="Open"/>
<menu_item_call label="СеÑÑ‚ÑŒ здеÑÑŒ" name="Object Sit"/>
<menu_item_call label="Ð’Ñтать" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/ru/menu_viewer.xml
index 0699314d97..d9425937c3 100644
--- a/indra/newview/skins/default/xui/ru/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/ru/menu_viewer.xml
@@ -26,6 +26,7 @@
<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">
@@ -37,6 +38,7 @@
<menu_item_call label="ДрузьÑ" name="My Friends"/>
<menu_item_call label="Группы" name="My Groups"/>
<menu_item_call label="Люди неподалеку" name="Active Speakers"/>
+ <menu_item_call label="Черный ÑпиÑок" name="Block List"/>
</menu>
<menu label="Мир" name="World">
<menu_item_call label="Добавить закладку на Ñто меÑто" name="Create Landmark Here"/>
@@ -122,6 +124,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 +179,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 +231,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"/>
@@ -287,6 +292,12 @@
<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"/>
@@ -304,7 +315,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"/>
@@ -371,7 +381,6 @@
<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"/>
diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml
index b4692385d1..85b7074253 100644
--- 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"/>
@@ -360,13 +366,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 +484,8 @@
Ошибка при Ñохранении Ñкомпилированного Ñкрипта по Ñледующей причине: [REASON]. Попробуйте Ñохранить Ñкрипт через некоторое времÑ.
</notification>
<notification name="StartRegionEmpty">
- Ðй-Ñй-Ñй, ваш Ñтартовый регион не определен.
-Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑтоположение» или «Мой дом».
+ Ваш Ñтартовый регион не определен.
+Введите название региона в поле «МеÑто Ñтарта» или выберите в качеÑтве меÑта Ñтарта «Мое поÑледнее меÑто» или «Мой дом».
<usetemplate name="okbutton" yestext="OK"/>
</notification>
<notification name="CouldNotStartStopScript">
@@ -495,6 +507,15 @@
</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="UnknownGPU">
Ð’ вашей ÑиÑтеме уÑтановлена графичеÑÐºÐ°Ñ ÐºÐ°Ñ€Ñ‚Ð°, которую [APP_NAME] не может раÑпознать.
Так чаÑто бывает, еÑли новое оборудование еще не было проверено на работу Ñ [APP_NAME]. Скорее вÑего, оно будет работать нормально, но, возможно, придетÑÑ Ð¾Ñ‚Ñ€ÐµÐ³ÑƒÐ»Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ параметры графики.
@@ -591,6 +612,9 @@
УбедитеÑÑŒ, что вÑе объекты разблокированы и что вы владеете вÑеми ими.
</notification>
+ <notification name="CannotLinkPermanent">
+ Объекты Ð½ÐµÐ»ÑŒÐ·Ñ ÑвÑзывать через границу региона.
+ </notification>
<notification name="CannotLinkDifferentOwners">
Ðевозможно объединить объекты: не у вÑех объектов один владелец.
@@ -969,6 +993,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">
@@ -1148,7 +1207,7 @@
Ð’Ñ‹ перемещены в ÑоÑедний регион.
</notification>
<notification name="AvatarMovedLast">
- Ваше поÑледнее меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно.
+ Требуемое вами меÑтоположение ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ÐµÐ´Ð¾Ñтупно.
Ð’Ñ‹ перемещены в ÑоÑедний регион.
</notification>
<notification name="AvatarMovedHome">
@@ -1167,7 +1226,6 @@
УÑтановка [APP_NAME] завершена.
ЕÑли вы иÑпользуете [SECOND_LIFE] впервые, Ð´Ð»Ñ Ð²Ñ…Ð¾Ð´Ð° в программу вам потребуетÑÑ Ñоздать аккаунт.
-ВернутьÑÑ Ð½Ð° [http://join.secondlife.com secondlife.com] Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð°ÐºÐºÐ°ÑƒÐ½Ñ‚Ð°?
<usetemplate name="okcancelbuttons" notext="Продолжить" yestext="Создать аккаунт..."/>
</notification>
<notification name="LoginPacketNeverReceived">
@@ -1685,83 +1743,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 +1918,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].
@@ -2108,14 +2210,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] и ввеÑти Ñту информацию?
@@ -2377,6 +2476,23 @@ http://secondlife.com/download.
<notification name="NoBuild">
Ð’ Ñтой облаÑти запрещено ÑтроительÑтво. ЗдеÑÑŒ вы не Ñможете Ñтроить или выкладывать объекты.
</notification>
+ <notification name="PathfindingDirty">
+ Ð’ регионе еÑÑ‚ÑŒ незавершенные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð¸Ñка пути. ЕÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ права на ÑтроительÑтво, воÑÑтановите регион, нажав кнопку «ВоÑÑтановить регион».
+ </notification>
+ <notification name="DynamicPathfindingDisabled">
+ Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути. Возможны Ð½Ð°Ñ€ÑƒÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñкриптовых объектов Ñ Ð¸Ñпользованием вызовов LSL поиÑка пути.
+ </notification>
+ <notification name="PathfindingRebakeNavmesh">
+ Изменение некоторых объектов в регионе может привеÑти к неправильному поведению других подвижных объектов. Чтобы иÑправить их поведение, нажмите кнопку «ВоÑÑтановить регион». Более Ð¿Ð¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ â€“ по ÑÑылке «Справка».
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Справка" ignoretext="Изменение некоторых объектов в регионе может привеÑти к неправильному поведению других подвижных объектов." name="okhelpignore" yestext="OK"/>
+ </notification>
+ <notification name="PathfindingCannotRebakeNavmesh">
+ Произошла ошибка. Возможно, неполадка в Ñети или на Ñервере, или у Ð²Ð°Ñ Ð½ÐµÑ‚ прав на ÑтроительÑтво. Иногда Ð´Ð»Ñ ÑƒÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ñтой проблемы доÑтаточно выйти и Ñнова войти.
+ <usetemplate name="okbutton" yestext="OK"/>
+ </notification>
<notification name="SeeAvatars">
Ðа Ñтом учаÑтке аватары и текÑтовый чат Ñкрыты от другого учаÑтка. Жителей за пределами Ñтого учаÑтка не будет видно, а они не будут видеть ваÑ. Обычный текÑтовый чат на канале 0 также блокируетÑÑ.
</notification>
@@ -2395,9 +2511,7 @@ http://secondlife.com/download.
Ð’Ñ‹ можете претендовать на публичную землю только в регионе, в котором вы находитеÑÑŒ.
</notification>
<notification name="RegionTPAccessBlocked">
- Вам Ð½ÐµÐ»ÑŒÐ·Ñ Ð±Ñ‹Ñ‚ÑŒ в Ñтом регионе из-за вашего рейтинга зрелоÑти. Подтвердите Ñвой возраÑÑ‚ и/или уÑтановите поÑледнюю верÑию клиента.
-
-Прочитайте в Базе знаний о доÑтупе к облаÑÑ‚Ñм Ñ Ñтим рейтингом зрелоÑти.
+ Ð’Ñ‹ пытаетеÑÑŒ поÑетить регион, контент в котором не ÑоответÑтвует вашим наÑтройкам. Попробуйте изменить наÑтройки в меню «Я &gt; ÐаÑтройки &gt; Общие».
</notification>
<notification name="URBannedFromRegion">
Вы забанены в регионе.
@@ -2408,11 +2522,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 +2628,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 +2749,12 @@ 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="ScriptDialog">
@@ -2927,6 +3058,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 +3233,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 +3313,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/ru/panel_group_invite.xml
index 3041046041..68dac5cd7e 100644
--- 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_login.xml b/indra/newview/skins/default/xui/ru/panel_login.xml
index 7928191fa6..f0877731c6 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
index a9d5569c7f..9283fc9e6e 100644
--- a/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/ru/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/ru/panel_region_debug.xml
index c21d2d7051..4be1e781fa 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/ru/panel_region_estate.xml
index 93b21704bc..bcfb974fcb 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/ru/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/ru/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/ru/sidepanel_item_info.xml
index 62095acbaf..0106ed50ac 100644
--- 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..e9dd3760b5 100644
--- 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>
@@ -95,6 +101,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..f9ded799bf 100644
--- a/indra/newview/skins/default/xui/ru/strings.xml
+++ b/indra/newview/skins/default/xui/ru/strings.xml
@@ -137,7 +137,7 @@
Выйти
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/index.php?lang=ru-RU&amp;sourceid=[sourceid]
</string>
<string name="LoginFailedViewerNotPermitted">
У клиента, которым вы пользуетеÑÑŒ, больше нет доÑтупа к игре Second Life. Загрузить новую верÑию клиента можно по адреÑу
@@ -883,6 +883,9 @@ support@secondlife.com.
<string name="ScriptQuestionCautionChatDenied">
Объекту «[OBJECTNAME]», который принадлежит пользователю «[OWNERNAME]» и находитÑÑ Ð² [REGIONPOS] в регионе «[REGIONNAME]», отказано в разрешении: [PERMISSIONS].
</string>
+ <string name="AdditionalPermissionsRequestHeader">
+ Разрешив доÑтуп к Ñвоему аккаунту, вы также разрешите объекту:
+ </string>
<string name="ScriptTakeMoney">
У Ð²Ð°Ñ Ð±ÐµÑ€ÑƒÑ‚ Linden-деньги
</string>
@@ -916,6 +919,9 @@ support@secondlife.com.
<string name="ControlYourCamera">
УправлÑÑ‚ÑŒ камерой
</string>
+ <string name="TeleportYourAgent">
+ Телепортировать ваÑ
+ </string>
<string name="NotConnected">
Ðет подключениÑ
</string>
@@ -997,6 +1003,9 @@ support@secondlife.com.
<string name="script_files">
Скрипты
</string>
+ <string name="dictionary_files">
+ Словари
+ </string>
<string name="AvatarSetNotAway">
Ðа меÑте
</string>
@@ -1402,6 +1411,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 +1432,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>
@@ -3852,6 +3873,12 @@ support@secondlife.com.
<string name="LocationCtrlSeeAVsTooltip">
Ð’Ñе жители Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… учаÑтков могут видеть аватары и общатьÑÑ Ð² чате
</string>
+ <string name="LocationCtrlPathfindingDirtyTooltip">
+ Возможны неполадки подвижных объектов в Ñтом регионе, пока регион не будет воÑÑтановлен.
+ </string>
+ <string name="LocationCtrlPathfindingDisabledTooltip">
+ Ð’ Ñтом регионе не разрешен динамичеÑкий поиÑк пути.
+ </string>
<string name="UpdaterWindowTitle">
Обновление [APP_NAME]
</string>
@@ -5006,6 +5033,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 +5063,10 @@ support@secondlife.com.
<string name="snapshot_quality_very_high">
Очень выÑокий
</string>
+ <string name="TeleportMaturityExceeded">
+ Житель не может поÑетить Ñтот регион.
+ </string>
+ <string name="UserDictionary">
+ [Пользователь]
+ </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
--- 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_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index 8fa12ea759..9cc9c7a220 100644
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -63,27 +63,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
--- 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_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_autoreplace.xml b/indra/newview/skins/default/xui/tr/floater_autoreplace.xml
new file mode 100644
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_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_hardware_settings.xml b/indra/newview/skins/default/xui/tr/floater_hardware_settings.xml
index 8e056b9b0d..b204389083 100644
--- 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_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_model_preview.xml b/indra/newview/skins/default/xui/tr/floater_model_preview.xml
index 0c7cabc6ea..c00cadd3bd 100644
--- 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_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_pathfinding_characters.xml b/indra/newview/skins/default/xui/tr/floater_pathfinding_characters.xml
new file mode 100644
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 100644
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 100644
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_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_spellcheck.xml b/indra/newview/skins/default/xui/tr/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml
index 4ef789f585..889425f23a 100644
--- 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"/>
- <check_box initial_value="true" label="Åžimdi uygula" name="apply_immediate_check"/>
+ <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/>
+ <check_box initial_value="true" label="Canlı Önizleme" 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 100644
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..4bf0372a8a 100644
--- 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."/>
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
--- 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_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_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
--- 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/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_inventory.xml b/indra/newview/skins/default/xui/tr/menu_inventory.xml
index 170cdebd24..51049427af 100644
--- 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_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_object.xml b/indra/newview/skins/default/xui/tr/menu_object.xml
index d60c68e5e9..72f7adf016 100644
--- a/indra/newview/skins/default/xui/tr/menu_object.xml
+++ b/indra/newview/skins/default/xui/tr/menu_object.xml
@@ -3,6 +3,8 @@
<menu_item_call label="Dokun" name="Object Touch"/>
<menu_item_call label="Düzenle" name="Edit..."/>
<menu_item_call label="Ä°nÅŸa Et" name="Build"/>
+ <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"/>
<menu_item_call label="Aç" name="Open"/>
<menu_item_call label="Buraya Otur" name="Object Sit"/>
<menu_item_call label="Kalk" name="Object Stand Up"/>
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
--- 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_viewer.xml b/indra/newview/skins/default/xui/tr/menu_viewer.xml
index d7b20bac4b..7a7faf6ac4 100644
--- a/indra/newview/skins/default/xui/tr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/tr/menu_viewer.xml
@@ -26,6 +26,7 @@
<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">
@@ -37,6 +38,7 @@
<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_call label="Engelleme Listesi" name="Block List"/>
</menu>
<menu label="Dünya" name="World">
<menu_item_call label="Bu Yeri Yer Ä°mlerine Ekle" name="Create Landmark Here"/>
@@ -122,6 +124,11 @@
<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>
<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"/>
@@ -172,7 +179,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 +231,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"/>
@@ -287,6 +292,12 @@
<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"/>
@@ -304,7 +315,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"/>
@@ -371,7 +381,6 @@
<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_item_call label="Parametreleri Varsayılana Zorla" name="Force Params to Default"/>
diff --git a/indra/newview/skins/default/xui/tr/notifications.xml b/indra/newview/skins/default/xui/tr/notifications.xml
index 6681cdac7a..488702f9ca 100644
--- 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"/>
@@ -360,13 +366,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 +484,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 +507,15 @@ 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="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 +612,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 +993,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">
@@ -1148,7 +1207,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 +1223,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.
@@ -1685,83 +1743,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 +1918,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.
@@ -2108,14 +2210,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?
@@ -2176,7 +2275,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.
@@ -2377,6 +2476,23 @@ 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="PathfindingRebakeNavmesh">
+ Bu bölgede belirli diğer nesneleri değiştirmek, hareket eden başka nesnelerin yanlış davranmasına neden olabilir. Hareket eden başka nesnelerin doğru davranmasını sağlamak için “Bölgeyi yeniden kaydet†düğmesine tıklayın. Daha fazla bilgi edinmek için “Yardım†seçimini yapın.
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="Yardım" ignoretext="Bu bölgede belirli diğer nesneleri değiştirmek, hareket eden başka nesnelerin yanlış davranmasına neden olabilir." name="okhelpignore" yestext="Tamam"/>
+ </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 +2511,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 +2522,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 +2628,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 +2749,12 @@ 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.
+
+Bu türden bir talebin yerinde olması nadir bir durumdur. 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="ScriptDialog">
@@ -2927,6 +3058,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 +3233,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 +3313,24 @@ 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>
</notifications>
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_group_invite.xml b/indra/newview/skins/default/xui/tr/panel_group_invite.xml
index 9b0c7f799a..4ba5761edb 100644
--- 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_login.xml b/indra/newview/skins/default/xui/tr/panel_login.xml
index acd6aa1921..28d316e46b 100644
--- 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_preferences_chat.xml b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
index 9caf95a122..231e8fc5fe 100644
--- a/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/tr/panel_preferences_chat.xml
@@ -29,5 +29,7 @@
<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"/>
+ <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_region_debug.xml b/indra/newview/skins/default/xui/tr/panel_region_debug.xml
index 6e15e0f6f6..834ece563f 100644
--- 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_estate.xml b/indra/newview/skins/default/xui/tr/panel_region_estate.xml
index f1df13df61..4a9028643f 100644
--- 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_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_question_toast.xml b/indra/newview/skins/default/xui/tr/panel_script_question_toast.xml
new file mode 100644
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_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_volume_pulldown.xml b/indra/newview/skins/default/xui/tr/panel_volume_pulldown.xml
new file mode 100644
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/sidepanel_item_info.xml b/indra/newview/skins/default/xui/tr/sidepanel_item_info.xml
index 81291a431c..86b684c497 100644
--- 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..b0b9ab7716 100644
--- 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>
@@ -95,6 +101,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..1be8f5974c 100644
--- a/indra/newview/skins/default/xui/tr/strings.xml
+++ b/indra/newview/skins/default/xui/tr/strings.xml
@@ -137,7 +137,7 @@
Çık
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/index.php?lang=tr-TR&amp;sourceid=[sourceid]
</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:
@@ -883,6 +883,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>
@@ -916,6 +919,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="ControlYourCamera">
Kameranızı kontrol etmek
</string>
+ <string name="TeleportYourAgent">
+ Sizi ışınlama
+ </string>
<string name="NotConnected">
Bağlı Değil
</string>
@@ -997,6 +1003,9 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin.
<string name="script_files">
Komut Dosyaları
</string>
+ <string name="dictionary_files">
+ Sözlükler
+ </string>
<string name="AvatarSetNotAway">
Uzakta DeÄŸil
</string>
@@ -1402,6 +1411,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 +1432,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>
@@ -3855,6 +3876,12 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun.
<string name="LocationCtrlSeeAVsTooltip">
Bu parselin dışında avatarlar görünür durumda ve sohbete izin veriliyor
</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
</string>
@@ -5007,6 +5034,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 +5064,10 @@ 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>
</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
--- 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
--- 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..643881e416 100644
--- a/indra/newview/skins/default/xui/zh/floater_about.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about.xml
@@ -5,10 +5,10 @@
[[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_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地å€å:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
[SERVER_VERSION]
[SERVER_RELEASE_NOTES_URL]
</floater.string>
@@ -20,10 +20,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 +37,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
--- 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
--- 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 100644
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 100644
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
--- 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 100644
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 100644
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
--- 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
--- 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
--- 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
--- 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..59751a3a46 100644
--- a/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/zh/floater_bulk_perms.xml
@@ -33,13 +33,13 @@
<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="下一個æ“有者能é€å‡ºæˆ–轉售這個物件"/>
+ <check_box label="æšåº¨" name="next_owner_copy"/>
+ <check_box initial_value="true" label="轉移" name="next_owner_transfer" tool_tip="下一個所有人å¯è´ˆé€æˆ–轉售這個物件"/>
<button label="確定" name="apply"/>
<button label="å–消" name="close"/>
</floater>
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
--- 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
--- 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_land.xml b/indra/newview/skins/default/xui/zh/floater_buy_land.xml
index 336d14747d..51bbd6a561 100644
--- 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
--- 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
--- 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 100644
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_color_picker.xml b/indra/newview/skins/default/xui/zh/floater_color_picker.xml
index a7ac78e419..fa7b795d4f 100644
--- 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_delete_env_preset.xml b/indra/newview/skins/default/xui/zh/floater_delete_env_preset.xml
new file mode 100644
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 100644
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
--- 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 100644
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 100644
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 100644
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 100644
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
--- 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 100644
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_gesture.xml b/indra/newview/skins/default/xui/zh/floater_gesture.xml
index a809cf085c..e7b1ed1de3 100644
--- 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
--- 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_hardware_settings.xml b/indra/newview/skins/default/xui/zh/floater_hardware_settings.xml
index 1465dcb256..9e3bb88ac0 100644
--- 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_how_to.xml b/indra/newview/skins/default/xui/zh/floater_how_to.xml
new file mode 100644
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_im_session.xml b/indra/newview/skins/default/xui/zh/floater_im_session.xml
index e8db97560e..808a0b6720 100644
--- a/indra/newview/skins/default/xui/zh/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/zh/floater_im_session.xml
@@ -2,7 +2,7 @@
<floater name="panel_im">
<layout_stack name="im_panels">
<layout_panel>
- <line_editor label="To" name="chat_editor"/>
+ <line_editor label="至" name="chat_editor"/>
</layout_panel>
</layout_stack>
</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
--- 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 100644
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..45a003d3c8 100644
--- a/indra/newview/skins/default/xui/zh/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/zh/floater_incoming_call.xml
@@ -4,28 +4,28 @@
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?
+ 是å¦é›¢é–‹ [CURRENT_CHAT] 並加入這個語音èŠå¤©ï¼Ÿ
</text>
<button label="接å—" label_selected="接å—" name="Accept"/>
<button label="拒絕" label_selected="拒絕" name="Reject"/>
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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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 100644
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 100644
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
--- 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
--- 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 100644
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 100644
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_object_weights.xml b/indra/newview/skins/default/xui/zh/floater_object_weights.xml
new file mode 100644
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
--- 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
--- 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
--- 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 100644
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 100644
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 100644
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
--- 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
--- 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 100644
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
--- 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 100644
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 100644
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
--- 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_preferences.xml b/indra/newview/skins/default/xui/zh/floater_preferences.xml
index 396a4893e0..b0a27e8c1f 100644
--- 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 100644
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
--- 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
--- 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_sound.xml b/indra/newview/skins/default/xui/zh/floater_preview_sound.xml
index 46844349de..d04428a36d 100644
--- 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
--- 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 100644
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
--- 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_report_abuse.xml b/indra/newview/skins/default/xui/zh/floater_report_abuse.xml
index 436f5cdcc5..8dbc216ab5 100644
--- 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_preview.xml b/indra/newview/skins/default/xui/zh/floater_script_preview.xml
index c3d05402c0..a6c6c76181 100644
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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_snapshot.xml b/indra/newview/skins/default/xui/zh/floater_snapshot.xml
index 9edc19969f..e86e20829f 100644
--- 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 100644
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_spellcheck.xml b/indra/newview/skins/default/xui/zh/floater_spellcheck.xml
new file mode 100644
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 100644
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
--- 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
--- 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
--- 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 100644
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 100644
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..e909a67e2c 100644
--- 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"/>
+ <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 100644
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..33c9ebeaf0 100644
--- 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,25 +447,25 @@
</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="以最後所é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æ質。這必須使用平é¢æ質映射方å¼ã€‚"/>
+ <check_box initial_value="false" label="å°é½Šå¹³é¢" name="checkbox planar align" tool_tip="以最後所é¸æ“‡çš„é¢ç‚ºåŸºæº–,å°é½Šå…¨éƒ¨æ‰€é¸æ“‡çš„é¢ä¸Šçš„æ質。 這必須使用平é¢æ質映射方å¼ã€‚"/>
<text name="rpt">
é‡è¦†æ¬¡æ•¸ / é¢
</text>
@@ -476,15 +506,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
--- 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
--- 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 100644
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 100644
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_voice_controls.xml b/indra/newview/skins/default/xui/zh/floater_voice_controls.xml
index 24b7efea4f..a3a7679957 100644
--- 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..81e0204262 100644
--- 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="語音變è²">
<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_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_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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml
index 1911a1aeff..c14a98c64b 100644
--- 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,7 @@
<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="丟棄" name="Drop"/>
</context_menu>
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..1d02464748 100644
--- 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,11 @@
<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="放大" name="Zoom In"/>
<menu_item_call label="支付" name="Pay..."/>
</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..32757bbff6 100644
--- 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,19 @@
<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..."/>
</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_edit.xml b/indra/newview/skins/default/xui/zh/menu_edit.xml
index d6eb87a6b0..bda640e5f3 100644
--- 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
--- 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
--- 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_hide_navbar.xml b/indra/newview/skins/default/xui/zh/menu_hide_navbar.xml
index dbb8ececaa..3f6820cb32 100644
--- 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_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/zh/menu_inspect_avatar_gear.xml
index 7385764e4c..f4e886ff67 100644
--- 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
--- 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
--- 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_inventory.xml b/indra/newview/skins/default/xui/zh/menu_inventory.xml
index 87d769af0d..7f745ffaa7 100644
--- 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
--- 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_land.xml b/indra/newview/skins/default/xui/zh/menu_land.xml
index 84941d138c..a87ab77dd0 100644
--- a/indra/newview/skins/default/xui/zh/menu_land.xml
+++ b/indra/newview/skins/default/xui/zh/menu_land.xml
@@ -1,7 +1,7 @@
<?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"/>
diff --git a/indra/newview/skins/default/xui/zh/menu_login.xml b/indra/newview/skins/default/xui/zh/menu_login.xml
index d6bf34c66e..c327b132a1 100644
--- 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,11 @@
<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="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
--- 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
--- 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 100644
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_navbar.xml b/indra/newview/skins/default/xui/zh/menu_navbar.xml
index 69df4929f2..d8356e6277 100644
--- 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
--- 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_object.xml b/indra/newview/skins/default/xui/zh/menu_object.xml
index ed41a4f0bf..4282c1e131 100644
--- 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="show_in_linksets"/>
+ <menu_item_call label="在角色中顯示" name="show_in_characters"/>
+ <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"/>
<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>
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..f4f93b0bdc 100644
--- 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,5 @@
<?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>
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..e85b4b7182 100644
--- 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"/>
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
--- 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_people_groups.xml b/indra/newview/skins/default/xui/zh/menu_people_groups.xml
index 1d78c1de0a..5768c554c9 100644
--- a/indra/newview/skins/default/xui/zh/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_groups.xml
@@ -3,6 +3,6 @@
<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="Activate"/>
+ <menu_item_call label="退出" name="Leave"/>
</menu>
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..38d5f3d324 100644
--- a/indra/newview/skins/default/xui/zh/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/zh/menu_people_nearby.xml
@@ -2,12 +2,12 @@
<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="移除朋å‹" 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_check label="å°éŽ–/ä¸å†å°éŽ–" name="Block/Unblock"/>
<menu_item_call label="發給瞬間傳é€è«‹æ±‚" name="teleport"/>
</context_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
--- 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_picks_plus.xml b/indra/newview/skins/default/xui/zh/menu_picks_plus.xml
index e962bd90d5..80922a757d 100644
--- 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_places_gear_folder.xml b/indra/newview/skins/default/xui/zh/menu_places_gear_folder.xml
index 7f4144d14d..27f0c7ebdb 100644
--- 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_profile_overflow.xml b/indra/newview/skins/default/xui/zh/menu_profile_overflow.xml
index ca637ae54d..f77e7090c4 100644
--- 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
--- 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_teleport_history_tab.xml b/indra/newview/skins/default/xui/zh/menu_teleport_history_tab.xml
index f9107a96ed..90e8098348 100644
--- 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
--- 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 100644
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
--- 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_http.xml b/indra/newview/skins/default/xui/zh/menu_url_http.xml
index cf953576f3..861cbfb975 100644
--- 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_slapp.xml b/indra/newview/skins/default/xui/zh/menu_url_slapp.xml
index afc15ce13c..6ce9a10d3e 100644
--- 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_viewer.xml b/indra/newview/skins/default/xui/zh/menu_viewer.xml
index b6bb79bcbc..ac0e9e7e35 100644
--- a/indra/newview/skins/default/xui/zh/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/zh/menu_viewer.xml
@@ -1,65 +1,92 @@
<?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_item_call label="行走 / 跑步 / 飛行…" name="Walk / run / fly"/>
</menu>
- <menu label="我的狀態" name="Status">
+ <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="購買 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_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="Gestures"/>
+ <menu_item_call label="朋å‹" name="My Friends"/>
+ <menu_item_call label="群組" name="My Groups"/>
<menu_item_call label="附近的人群" name="Active Speakers"/>
+ <menu_item_call label="å°éŽ–清單" name="Block List"/>
</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">
@@ -97,65 +124,69 @@
<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"/>
<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="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 +196,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 +231,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 +264,71 @@
<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>
+ <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_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="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="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"/>
</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 +342,24 @@
<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="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="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_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,19 +369,18 @@
<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_item_call label="強制åƒæ•¸ç‚ºé è¨­å€¼" name="Force Params to Default"/>
@@ -345,47 +388,56 @@
<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 +455,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
--- 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
--- 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/mime_types.xml b/indra/newview/skins/default/xui/zh/mime_types.xml
index 8ac1bf6920..70af2d2f19 100644
--- 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
--- 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
--- 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..9fecf2c104 100644
--- 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,33 @@ 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="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 +221,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 +413,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 +426,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 +442,101 @@ 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="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 +546,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 +588,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 +667,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 +711,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 +844,7 @@ Cannot find the region this land is in.
</notification>
<notification name="CannotDeedLandNoRegion">
無法讓渡土地:
-無法發ç¾é€™å¡ŠåœŸåœ°æ‰€åœ¨çš„地å€ã€‚
+找ä¸åˆ°é€™åœŸåœ°æ‰€åœ¨çš„地å€ã€‚
</notification>
<notification name="CannotDeedLandMultipleSelected">
無法讓渡土地:
@@ -802,7 +860,7 @@ Cannot find the region this land is in.
</notification>
<notification name="CannotDeedLandNoTransfer">
無法讓渡土地:
-æ­¤ [REGION] 地å€ä¸¦ä¸å…許土地轉移。
+「[REGION]ã€åœ°å€ä¸å…許土地轉移。
</notification>
<notification name="CannotReleaseLandWatingForServer">
無法放棄土地:
@@ -823,11 +881,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 +903,7 @@ Cannot find the region this land is in.
<notification name="CannotDivideLandNothingSelected">
無法分割土地:
-無地段被é¸å–。
+未é¸æ“‡åœ°æ®µã€‚
</notification>
<notification name="CannotDivideLandPartialSelection">
無法分割土地:
@@ -854,22 +912,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 +949,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 +993,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 +1058,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 +1066,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="DisplaySetToRecommendedGPUChange">
+ 由於你的顯åƒå¡æœ‰æ‰€è®Šæ›´ï¼Œå·²å°‡é¡¯ç¤ºç‹€æ…‹è¨­ç‚ºæŽ¨è–¦æŽ¡ç”¨çš„等級。
+原顯åƒå¡ï¼š[LAST_GPU]
+新顯åƒå¡ï¼š[THIS_GPU]
</notification>
- <notification name="DisplaySetToRecommended">
- Display settings have been set to recommended levels based on your system configuration.
+ <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 +1218,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 +1235,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 +1306,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,89 +1375,86 @@ 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]
-We must restart [APP_NAME] to install the update.
+我門必須é‡æ–°å•Ÿå‹• [APP_NAME] 以安è£æ›´æ–°ã€‚
<usetemplate name="okbutton" yestext="確定"/>
</notification>
<notification name="RequiredUpdateDownloadedDialog">
@@ -1375,8 +1462,8 @@ We must restart [APP_NAME] to install the update.
<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 +1475,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,10 +1499,10 @@ 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; 群組的æˆå“¡ã€‚
@@ -1427,57 +1514,57 @@ We must restart [APP_NAME] to install the update.
<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>
<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 +1574,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 +1584,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 +1672,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,251 +1730,295 @@ 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/ 塗鴉牆]以察看你的帳戶歷å²ç´€éŒ„?
@@ -1892,58 +2028,70 @@ Move the inventory item(s)?
你確定你è¦çµæŸé€€å‡ºï¼Ÿ
<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="確定"/>
@@ -1951,9 +2099,9 @@ Do you want to replace it with the selected object?
</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.
+ ä½ ç¾åœ¨è™•æ–¼å¿™ç¢Œæ¨¡å¼ï¼Œé€™æ„味著你付費後ä»å°‡ä¸æœƒæ”¶åˆ°ä»»ä½•ç‰©é …。
-Would you like to leave Busy Mode before completing this transaction?
+你是å¦è¦å…ˆé›¢é–‹å¿™ç¢Œæ¨¡å¼ï¼Œå†å®Œæˆäº¤æ˜“?
<form name="form">
<ignore name="ignore" text="當我在忙碌模å¼æ™‚,將è¦æ”¯ä»˜é‡‘錢或給他人物件"/>
<button ignore="總是離開忙碌模å¼" name="Yes" text="確定"/>
@@ -1961,7 +2109,7 @@ Would you like to leave Busy Mode before completing this transaction?
</form>
</notification>
<notification name="ConfirmDeleteProtectedCategory">
- 資料夾 &apos;[FOLDERNAME]&apos; 是系統資料夾。刪除系統資料夾將導致ä¸ç©©å®šã€‚你確定你è¦åˆªé™¤å®ƒï¼Ÿ
+ 「[FOLDERNAME]ã€å±¬æ–¼ç³»çµ±è³‡æ–™å¤¾ã€‚ 刪除系統資料夾å¯èƒ½å°Žè‡´ç³»çµ±ä¸ç©©å®šã€‚ 你確定è¦åŠ ä»¥åˆªé™¤ï¼Ÿ
<usetemplate ignoretext="在我刪除系統資料夾å‰ç¢ºèª" name="okcancelignore" notext="å–消" yestext="確定"/>
</notification>
<notification name="ConfirmEmptyTrash">
@@ -1972,6 +2120,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 +2140,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 +2149,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 name="WLRegionApplyFail">
+ 抱歉,設定無法套用到地å€ã€‚ 離開地å€å†è¿”回也許å¯ä»¥è§£æ±ºé€™å€‹å•é¡Œã€‚ 所得的原因為:[FAIL_REASON]
</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>
- <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 +2190,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 +2201,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 +2235,38 @@ 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; 上線
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ç›®å‰åœ¨ç·šä¸Š
</notification>
<notification name="FriendOffline">
- &lt;nolink&gt;[NAME]&lt;/nolink&gt; 離線
+ &lt;nolink&gt;[NAME]&lt;/nolink&gt; ç›®å‰é›¢ç·š
</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 +2275,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 +2290,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 +2307,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 +2349,7 @@ Please select a single object.
[NAME] è¬çµ•ä½ æ供的收ç´å€ç‰©å“。
</notification>
<notification name="ObjectMessage">
- [NAME]: [MESSAGE]
+ [NAME]:[MESSAGE]
</notification>
<notification name="CallingCardAccepted">
ä½ çš„å片已被接å—。
@@ -2220,24 +2358,25 @@ 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;).
+ è¦è¯çµ¡å¦‚「[NAME]ã€çš„任何一ä½å±…民,請點按「人群ã€æŒ‰éˆ•ï¼Œå¾žæ‰“開的視窗中é¸æ“‡ä¸€ä½å±…民,å†é»žæŒ‰è¦–窗底下的「IMã€ã€‚
+
+ (你還å¯ä»¥å¾žæ¸…單直接按兩下å字,或按滑鼠å³éµï¼Œé¸æ“‡ã€Œ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 +2387,9 @@ Try selecting a smaller piece of land.
<notification name="PaymentSent">
[MESSAGE]
</notification>
+ <notification name="PaymentFailure">
+ [MESSAGE]
+ </notification>
<notification name="EventNotification">
活動通知:
@@ -2259,179 +2401,205 @@ 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="PathfindingRebakeNavmesh">
+ 更改本地å€çš„æŸäº›ç‰©ä»¶å°‡å°Žè‡´å…¶ä»–移動物件的é‹ä½œç™¼ç”Ÿå•é¡Œã€‚ è¦ä½¿ç§»å‹•ç‰©ä»¶æ­£å¸¸é‹ä½œï¼Œè«‹é»žæŒ‰ã€Œé‡æ–°ç”¢å‡ºåœ°å€ã€æŒ‰éˆ•ã€‚ 欲ç²çŸ¥è©³æƒ…è«‹é¸æ“‡ã€Œå¹«åŠ©ã€ã€‚
+ <url name="url">
+ http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer
+ </url>
+ <usetemplate helptext="幫助" ignoretext="更改本地å€çš„æŸäº›ç‰©ä»¶å°‡å°Žè‡´å…¶ä»–移動物件的é‹ä½œç™¼ç”Ÿå•é¡Œã€‚" name="okhelpignore" yestext="確定"/>
+ </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 +2616,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 +2657,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 +2692,206 @@ 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.
-
-Grant this request?
+ 警告:物件 &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos; è¦æ±‚全權存å–你的林登幣帳戶。 你如果å…許存å–帳戶,它將å¯åœ¨ä»»ä½•æ™‚候從你帳戶å–走資金,或完全加以清空,或定期å–走部分資金,且ä¸æœƒç™¼å‡ºè­¦å‘Šã€‚
+
+這很å¯èƒ½æ˜¯ç¨®ä¸ç•¶çš„è¦æ±‚。 如果你ä¸å®Œå…¨çž­è§£å®ƒç‚ºä½•è¦æ±‚å­˜å–你的帳戶,請勿å…准。
<form name="form">
- <button name="Grant" text="Grant"/>
- <button name="Deny" text="Deny"/>
- <button name="Details" text="細節..."/>
+ <button name="Grant" text="å…許全權存å–"/>
+ <button name="Deny" 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 +2900,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 +2976,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 +3118,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 +3298,29 @@ 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>
</notifications>
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..1c8b56b3d6 100644
--- 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,28 +1,28 @@
<?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="這ä½æœ‹å‹èƒ½åœ¨åœ°åœ–上找到你的ä½ç½®"/>
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
--- 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
--- 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_chiclet_bar.xml b/indra/newview/skins/default/xui/zh/panel_chiclet_bar.xml
new file mode 100644
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
--- 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_item.xml b/indra/newview/skins/default/xui/zh/panel_clothing_list_item.xml
index 1185336a2d..55e72f5347 100644
--- 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
--- 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_edit_alpha.xml b/indra/newview/skins/default/xui/zh/panel_edit_alpha.xml
index eda4e99a13..32765a3e16 100644
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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_pick.xml b/indra/newview/skins/default/xui/zh/panel_edit_pick.xml
index 6ac7226185..faee42fd0e 100644
--- 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
--- 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_shirt.xml b/indra/newview/skins/default/xui/zh/panel_edit_shirt.xml
index f8ff76aa9b..bc69f2ffc4 100644
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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_notices.xml b/indra/newview/skins/default/xui/zh/panel_group_notices.xml
index 26273dd9ce..ba5f4f1bba 100644
--- 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
--- 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
--- 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
--- 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_landmark_info.xml b/indra/newview/skins/default/xui/zh/panel_landmark_info.xml
index d86ba7bc7c..b50aa24d3f 100644
--- 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_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml
index b227fbcfc8..672d9bb1a2 100644
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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 100644
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 100644
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..4361b588d8 100644
--- 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 來喊å«"/>
+ <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
--- 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_outbox_inventory.xml b/indra/newview/skins/default/xui/zh/panel_outbox_inventory.xml
new file mode 100644
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
--- 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
--- 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_list.xml b/indra/newview/skins/default/xui/zh/panel_outfits_list.xml
index a4b041469b..cfb0180f9c 100644
--- 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_people.xml b/indra/newview/skins/default/xui/zh/panel_people.xml
index 9c265622fa..59ea7b70e2 100644
--- a/indra/newview/skins/default/xui/zh/panel_people.xml
+++ b/indra/newview/skins/default/xui/zh/panel_people.xml
@@ -1,23 +1,23 @@
<?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"/>
@@ -25,7 +25,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
<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你的朋å‹æ¸…å–®"/>
+ <button name="add_friend_btn" tool_tip="添加所é¸çš„居民到你的朋å‹æ¸…å–®"/>
</panel>
</panel>
<panel label="我的朋å‹" name="friends_panel">
@@ -39,7 +39,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
<menu_button name="friends_viewsort_btn" tool_tip="顯示é¡å¤–é¸é …"/>
</layout_panel>
<layout_panel name="add_btn_panel">
- <button name="add_btn" tool_tip="å‘å±…æ°‘æ出加為好å‹é‚€è«‹"/>
+ <button name="add_btn" tool_tip="å‘居民發出交å‹é‚€è«‹"/>
</layout_panel>
<layout_panel name="trash_btn_panel">
<dnd_button name="del_btn" tool_tip="由你的朋å‹æ¸…單移除所é¸æ“‡çš„人"/>
@@ -66,17 +66,17 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
<layout_panel name="view_profile_btn_lp">
<button label="檔案" name="view_profile_btn" tool_tip="顯示圖片ã€ç¾¤çµ„與其他居民資訊"/>
</layout_panel>
- <layout_panel name="chat_btn_lp">
+ <layout_panel name="im_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 name="call_btn_lp">
+ <button label="通話" name="call_btn" tool_tip="和這ä½å±…民通話"/>
</layout_panel>
- <layout_panel name="chat_btn_lp">
+ <layout_panel name="share_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 name="teleport_btn_lp">
+ <button label="瞬間傳é€" name="teleport_btn" tool_tip="發出瞬間傳é€é‚€è«‹"/>
</layout_panel>
</layout_stack>
<layout_stack name="bottom_bar_ls1">
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
--- 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
--- 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
--- 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/floater_postcard.xml b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml
index 6f6b75f468..563c4fca3c 100644
--- a/indra/newview/skins/default/xui/zh/floater_postcard.xml
+++ b/indra/newview/skins/default/xui/zh/panel_postcard_message.xml
@@ -1,33 +1,21 @@
<?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>
+<panel name="panel_postcard_message">
<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>
+</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 100644
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
--- 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_chat.xml b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
index 738c77fd08..cf2f81d313 100644
--- a/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/zh/panel_preferences_chat.xml
@@ -27,31 +27,9 @@
</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>
+ <spinner label="附近èŠå¤©å…§å®¹æ示框åœé§æ™‚間:" name="nearby_toasts_lifetime"/>
+ <spinner label="附近èŠå¤©å…§å®¹æ示框消退時間:" name="nearby_toasts_fadingtime"/>
+ <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
--- 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..7e67a0d02d 100644
--- 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>
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..3948a48992 100644
--- 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
--- 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_setup.xml b/indra/newview/skins/default/xui/zh/panel_preferences_setup.xml
index efefb92df6..a607a7c33b 100644
--- 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="1"/>
+ <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,8 @@
<combo_box.item label="自動安è£" name="Install_automatically"/>
<combo_box.item label="手動下載åŠå®‰è£" name="Install_manual"/>
</combo_box>
+ <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
--- 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
--- 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
--- 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
--- 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 100644
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
--- 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
--- 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
--- 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..29e9a35869 100644
--- 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,12 +22,14 @@
<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"/>
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
--- 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
--- 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 100644
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_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_snapshot_inventory.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_inventory.xml
new file mode 100644
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 100644
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 100644
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 100644
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 100644
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 100644
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
--- 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
--- 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
--- 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_volume_pulldown.xml b/indra/newview/skins/default/xui/zh/panel_volume_pulldown.xml
new file mode 100644
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
--- 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..767bcecde7 100644
--- 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
--- 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
--- 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
--- 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..982dde4010 100644
--- 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,23 @@
創造者:
</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>
<panel name="perms_inv">
<text name="perm_modify">
@@ -74,27 +80,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 +124,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..3f17324006 100644
--- 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,138 @@
çµæŸé€€å‡º
</string>
<string name="create_account_url">
- http://join.secondlife.com/
+ http://join.secondlife.com/?sourceid=[sourceid]
+ </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 +295,7 @@
(無å稱)
</string>
<string name="TooltipOwner">
- æ“有者:
+ 所有人:
</string>
<string name="TooltipPublic">
公開
@@ -196,60 +333,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">
@@ -304,7 +471,7 @@
æœå°‹ä¸­...
</string>
<string name="NoneFound">
- 未發ç¾ã€‚
+ 查無çµæžœã€‚
</string>
<string name="RetrievingData">
檢索...
@@ -328,7 +495,7 @@
(無)
</string>
<string name="AvalineCaller">
- Avaline Caller [ORDER]
+ Avaline 通話者 [ORDER]
</string>
<string name="AssetErrorNone">
無錯誤
@@ -355,10 +522,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 +558,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 +576,7 @@
å¿«ç…§
</string>
<string name="lost and found">
- Lost and Found
+ 失物招領
</string>
<string name="targa image">
targa 圖åƒ
@@ -438,6 +605,9 @@
<string name="symbolic folder link">
資料夾è¯çµ
</string>
+ <string name="mesh">
+ 網é¢
+ </string>
<string name="AvatarEditingAppearance">
(外觀編輯中)
</string>
@@ -457,88 +627,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 +717,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 +774,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 +827,9 @@
<string name="anim_yes_head">
是
</string>
+ <string name="multiple_textures">
+ 多個
+ </string>
<string name="texture_loading">
載入中...
</string>
@@ -664,19 +837,19 @@
離線
</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="whisper">
低語:
@@ -700,34 +873,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">
變更它的權é™
@@ -738,6 +914,9 @@
<string name="ControlYourCamera">
控制你的æ”影機
</string>
+ <string name="TeleportYourAgent">
+ 瞬間傳é€ä½ æœ¬äºº
+ </string>
<string name="NotConnected">
未è¯æŽ¥
</string>
@@ -799,7 +978,7 @@
AVI 視頻檔案
</string>
<string name="xaf_animation_file">
- XAF Anim File
+ XAF 動畫檔案
</string>
<string name="xml_file">
XML 檔案
@@ -816,6 +995,12 @@
<string name="choose_the_directory">
é¸æ“‡ç›®éŒ„
</string>
+ <string name="script_files">
+ 腳本
+ </string>
+ <string name="dictionary_files">
+ å­—å…¸
+ </string>
<string name="AvatarSetNotAway">
éžé›¢é–‹
</string>
@@ -991,19 +1176,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 +1227,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 +1310,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 +1322,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 +1377,7 @@
收ç´å€
</string>
<string name="InvFolder Uncompressed Images">
- Uncompressed Images
+ 未壓縮圖åƒ
</string>
<string name="InvFolder Body Parts">
身體部ä½
@@ -1148,10 +1389,10 @@
相簿
</string>
<string name="InvFolder Lost And Found">
- Lost And Found
+ 失物招領
</string>
<string name="InvFolder Uncompressed Sounds">
- 無壓縮è²éŸ³
+ 未壓縮è²éŸ³
</string>
<string name="InvFolder Animations">
動作
@@ -1165,6 +1406,12 @@
<string name="InvFolder favorite">
我的最愛
</string>
+ <string name="InvFolder Favorites">
+ 我的最愛
+ </string>
+ <string name="InvFolder favorites">
+ 我的最愛
+ </string>
<string name="InvFolder Current Outfit">
ç›®å‰è£æ‰®
</string>
@@ -1177,17 +1424,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 +1473,13 @@
橡膠
</string>
<string name="Light">
- Light
+ å…‰æº
</string>
<string name="KBShift">
- Shift
+ Shift éµ
</string>
<string name="KBCtrl">
- Ctrl
+ Ctrl éµ
</string>
<string name="Chest">
胸部
@@ -1250,7 +1512,7 @@
骨盆
</string>
<string name="Mouth">
- 嘴
+ 嘴巴
</string>
<string name="Chin">
下巴
@@ -1309,23 +1571,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 +1635,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 +1695,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 +1725,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 +1758,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 +1802,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 +1823,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 +1940,34 @@
左胸肌
</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="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 +1976,16 @@
[mthnum,datetime,slt]/[day,datetime,slt]
</string>
<string name="PanelContentsTooltip">
- 物件的內容
+ 物件內容
</string>
<string name="PanelContentsNewScript">
新腳本
</string>
<string name="BusyModeResponseDefault">
- 你傳é€è¨Šæ¯çš„å±…æ°‘ç›®å‰è™•æ–¼å¿™ç¢Œæ¨¡å¼ä¸­ï¼Œé€™æ„味著他è¦æ±‚ä¸è¢«æ‰“擾。你所傳的訊æ¯ä»å°‡æœƒç•™å­˜ä¸¦é¡¯ç¤ºæ–¼ IM é¢æ¿ä¸Šä¾›ä»–ç¨å¾Œæ™‚查閱。
+ 你傳訊éŽåŽ»çš„å±…æ°‘ç›®å‰è™•æ–¼å¿™ç¢Œç‹€æ…‹ï¼Œé€™æ„味著他è¦æ±‚ä¸è¢«æ‰“擾。 你的訊æ¯ä»å°‡ç•™å­˜ä¸¦é¡¯ç¤ºæ–¼å°ï¿½ï¿½ï¿½çš„ IM é¢æ¿ä¸Šä¾›ç¨å¾ŒæŸ¥é–±ã€‚
</string>
<string name="MuteByName">
- (由å稱)
+ (按å稱)
</string>
<string name="MuteAgent">
(居民)
@@ -1726,12 +2000,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 +2014,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 +2042,89 @@
屬性
</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="GroupMoneyDate">
+ [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]
</string>
<string name="ViewerObjectContents">
- Contents
+ 內容
</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 +2160,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 +2196,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 +2256,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 +2310,7 @@
多媒體
</string>
<string name="Play Media">
- 播放ï¼æš«åœ 媒體
+ 播放/æš«åœåª’é«”
</string>
<string name="MBCmdLineError">
解æžå‘½ä»¤åˆ—時發ç¾éŒ¯èª¤ã€‚
@@ -2038,1510 +2321,1510 @@
[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="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 +3868,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 +3887,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 +3899,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 +3908,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 +3923,46 @@ 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="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
+ [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 +3971,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 +4016,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 +4043,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 +4112,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 +4171,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
新襪å­
</string>
<string name="New Jacket">
- 新夾克
+ 新外套
</string>
<string name="New Gloves">
新手套
@@ -3912,7 +4222,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
女性姿勢
</string>
<string name="Other Gestures">
- 其他姿勢
+ 其他���勢
</string>
<string name="Speech Gestures">
演說姿勢
@@ -3921,91 +4231,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 +4409,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 +4445,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 +4481,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
刪除所é¸å–的物å“?
</string>
<string name="DeleteItem">
- 刪除所é¸å–的物å“?
+ 刪除所é¸å–的物���?
</string>
<string name="EmptyOutfitText">
沒有任何物å“在這個è£æ‰®å…§
@@ -4099,72 +4490,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 +4600,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 +4789,7 @@ Try enclosing path to the editor with double quotes.
M
</string>
<string name="N">
- N
+ 北
</string>
<string name="O">
O
@@ -4407,7 +4804,7 @@ Try enclosing path to the editor with double quotes.
R
</string>
<string name="S">
- S
+ å—
</string>
<string name="T">
T
@@ -4419,7 +4816,7 @@ Try enclosing path to the editor with double quotes.
V
</string>
<string name="W">
- W
+ 西
</string>
<string name="X">
X
@@ -4431,24 +4828,243 @@ 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_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_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>
</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
--- 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/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index c970d79975..3ba25f3c10 100644
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -84,19 +84,25 @@ namespace tut
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<>
@@ -107,45 +113,43 @@ namespace tut
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
}
@@ -156,21 +160,35 @@ namespace tut
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
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<>
@@ -180,55 +198,73 @@ namespace tut
cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
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
}
@@ -239,24 +275,16 @@ namespace tut
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);
- 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/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp
index 18cf4e7419..2bc6772d86 100644
--- 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/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 9e321db889..7705b4c567 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -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"
@@ -114,8 +115,9 @@ LLGridManager::~LLGridManager()
{
}
-void LLGridManager::addGrid(LLSD& grid_data)
+bool LLGridManager::addGrid(LLSD& grid_data)
{
+ return true;
}
LLGridManager::LLGridManager()
:
@@ -136,7 +138,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
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 +153,6 @@ bool LLGridManager::isInProductionGrid()
return false;
}
-void LLGridManager::saveFavorites()
-{}
std::string LLGridManager::getSLURLBase(const std::string& grid_name)
{
return "myslurl";
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index f96f79006a..09343ef227 100644
--- 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,8 +31,8 @@
#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) {}
@@ -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/lltranslate_test.cpp b/indra/newview/tests/lltranslate_test.cpp
index 10e37fae97..fd9527d631 100644
--- 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) {}
@@ -314,7 +309,7 @@ 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&, LLPointer<LLCurl::Responder>, const LLSD&, const F32) {}
LLBufferStream::LLBufferStream(const LLChannelDescriptors& channels, LLBufferArray* buffer)
: std::iostream(&mStreamBuf), mStreamBuf(channels, buffer) {}
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index 3c89b64d52..a1e97ea17e 100644
--- 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,8 +31,8 @@
#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) {}
@@ -81,26 +81,57 @@ 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>keyname</key><string>util.foobar.lindenlab.com</string>"
+ " </map>"
+ " </map>"
+ "</llsd>"
+ ;
// -------------------------------------------------------------------------------------------
// TUT
// -------------------------------------------------------------------------------------------
@@ -116,63 +147,89 @@ 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("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 +237,172 @@ 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("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("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/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 36267803e3..ea75d4f4f6 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -28,6 +28,7 @@ $/LicenseInfo$
"""
import sys
import os.path
+import errno
import re
import tarfile
import time
@@ -74,23 +75,30 @@ class ViewerManifest(LLManifest):
# 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")
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)
+
self.end_prefix("app_settings")
if self.prefix(src="character"):
@@ -107,7 +115,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 +132,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)
@@ -142,14 +156,9 @@ class ViewerManifest(LLManifest):
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)
+ # build.sh. It's only created for a build.sh build.
+ if not self.path2basename(os.path.join(os.pardir, os.pardir), "summary.json"):
+ print "No summary.json file"
def login_channel(self):
"""Channel reported for login and upgrade purposes ONLY;
@@ -320,13 +329,13 @@ class WindowsManifest(ViewerManifest):
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=""):
@@ -360,9 +369,7 @@ class WindowsManifest(ViewerManifest):
# Get fmod dll, continue if missing
- try:
- self.path("fmod.dll")
- except:
+ if not self.path("fmod.dll"):
print "Skipping fmod.dll"
# For textures
@@ -393,6 +400,9 @@ class WindowsManifest(ViewerManifest):
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':
@@ -527,6 +537,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]
@@ -659,6 +670,7 @@ class DarwinManifest(ViewerManifest):
# 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")
@@ -699,85 +711,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)
+ 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",
+ "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',
+ 'SLVoice',
+ ):
+ self.path2basename(libdir, libfile)
- try:
- # FMOD for sound
- self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
- except:
- print "Skipping FMOD - not found"
+ # FMOD for sound
+ libfile = "libfmodwrapper.dylib"
+ path_optional(os.path.join(self.args['configuration'], libfile), 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"),
+ ("mac_updater", "mac-updater.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")
@@ -805,6 +814,30 @@ class DarwinManifest(ViewerManifest):
self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
def package_finish(self):
+ # 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()
+ })
+
channel_standin = 'Second Life Viewer' # hah, our default channel is not usable on its own
if not self.default_channel():
channel_standin = self.channel()
@@ -920,20 +953,25 @@ 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.path("../linux_updater/linux-updater", "linux-updater.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 +987,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")
@@ -1025,9 +1059,21 @@ class Linux_i686Manifest(LinuxManifest):
super(Linux_i686Manifest, self).construct()
if self.prefix("../packages/lib/release", dst="lib"):
- self.path("libapr-1.so*")
- self.path("libaprutil-1.so*")
- self.path("libbreakpad_client.so*")
+ self.path("libapr-1.so")
+ self.path("libapr-1.so.0")
+ 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.4.1")
+ self.path("libboost_program_options-mt.so.*")
+ self.path("libboost_regex-mt.so.*")
+ self.path("libboost_thread-mt.so.*")
+ self.path("libboost_filesystem-mt.so.*")
+ self.path("libboost_signals-mt.so.*")
+ self.path("libboost_system-mt.so.*")
+ self.path("libbreakpad_client.so.0.0.0")
+ self.path("libbreakpad_client.so.0")
+ self.path("libbreakpad_client.so")
self.path("libcollada14dom.so")
self.path("libdb*.so")
self.path("libcrypto.so.*")
@@ -1043,7 +1089,8 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libopenjpeg.so*")
self.path("libdirectfb-1.4.so.5")
self.path("libfusion-1.4.so.5")
- self.path("libdirect-1.4.so.5")
+ 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
@@ -1065,7 +1112,13 @@ class Linux_i686Manifest(LinuxManifest):
# previous call did, without having to explicitly state the
# version number.
self.path("libfontconfig.so.*.*")
- self.path("libtcmalloc.so*") #formerly called google perf tools
+ 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")
pass
@@ -1100,5 +1153,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/test/lluuidhashmap_tut.cpp b/indra/test/lluuidhashmap_tut.cpp
index 0544e832ce..408bc3faf1 100644
--- 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,133 @@ 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 (gDirUtilp->fileExists(savefile))
{
- LLUUID id;
- id.generate();
- UUIDTableEntry entry(id, i);
- hashTable.set(id, entry);
- idList[i] = id;
+ // 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
+ {
+ // savefile does not exist (normal case): 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/test.cpp b/indra/test/test.cpp
index 9d24383bcc..dc8580fe69 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -181,13 +181,16 @@ 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;
}
@@ -245,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; }
@@ -451,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)
@@ -477,17 +489,24 @@ int main(int argc, char **argv)
#ifndef LL_WINDOWS
::testing::InitGoogleMock(&argc, argv);
#endif
- LLError::initForApplication(".");
- LLError::setFatalFunction(wouldHaveCrashed);
- LLError::setDefaultLevel(LLError::LEVEL_ERROR);
- // ^ possibly overridden by --debug, LOGTEST or LOGFAIL
-
// 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::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();
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index d480b63094..bdcb068200 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -271,6 +271,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/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index c6aa9b0f11..5edbbf9914 100644
--- 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,10 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
}
-void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl,
+void LLUpdateChecker::checkVersion(std::string const & protocolVersion, std::string const & hostUrl,
std::string const & servicePath, std::string channel, std::string version)
{
- mImplementation->check(protocolVersion, hostUrl, servicePath, channel, version);
+ mImplementation->checkVersion(protocolVersion, hostUrl, servicePath, channel, version);
}
@@ -120,7 +91,7 @@ LLUpdateChecker::Implementation::~Implementation()
}
-void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl,
+void LLUpdateChecker::Implementation::checkVersion(std::string const & protocolVersion, std::string const & hostUrl,
std::string const & servicePath, std::string channel, std::string version)
{
llassert(!mInProgress);
@@ -132,13 +103,7 @@ void LLUpdateChecker::Implementation::check(std::string const & protocolVersion,
std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, channel, version);
LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
- // 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);
}
void LLUpdateChecker::Implementation::completed(U32 status,
@@ -179,7 +144,18 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & protoc
#ifdef LL_WINDOWS
static const char * platform = "win";
#elif LL_DARWIN
- static const char * platform = "mac";
+ long versMin;
+ Gestalt(gestaltSystemVersionMinor, &versMin);
+
+ static const char *platform;
+ if (versMin == 5) //OS 10.5
+ {
+ platform = "mac_legacy";
+ }
+ else
+ {
+ platform = "mac";
+ }
#else
static const char * platform = "lnx";
#endif
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index cea1f13647..23f62a7c5e 100644
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -29,6 +29,7 @@
#include <boost/shared_ptr.hpp>
+#include "llhttpclient.h"
//
// Implements asynchronous checking for updates.
@@ -36,7 +37,36 @@
class LLUpdateChecker {
public:
class Client;
- class Implementation;
+ class Implementation:
+
+ public LLHTTPClient::Responder
+ {
+ public:
+ Implementation(Client & client);
+ ~Implementation();
+ void checkVersion(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);
+ };
+
// An exception that may be raised on check errors.
class CheckError;
@@ -44,11 +74,11 @@ 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,
+ void checkVersion(std::string const & protocolVersion, std::string const & hostUrl,
std::string const & servicePath, std::string channel, std::string version);
private:
- boost::shared_ptr<Implementation> mImplementation;
+ LLPointer<Implementation> mImplementation;
};
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 2e18218667..bc73c72ddc 100644
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -509,7 +509,7 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
}
else
{
- mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
+ mUpdateChecker.checkVersion(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
setState(LLUpdaterService::CHECKING_FOR_UPDATE);
}
}
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index e19d5724f1..a49bc4161e 100644
--- 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,7 +44,7 @@
*****************************************************************************/
LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
{}
-void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl,
+void LLUpdateChecker::checkVersion(std::string const & protocolVersion, std::string const & hostUrl,
std::string const & servicePath, std::string channel, std::string version)
{}
LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
@@ -63,7 +63,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,7 +78,9 @@ 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() {}